发出“exec &>filename”后将输出恢复到终端

use*_*279 17 io-redirection

我正在尝试执行以下操作:

exec &>filename
Run Code Online (Sandbox Code Playgroud)

在此之后,我看不到任何内容,包括我输入的内容,好吧。

我疯狂地尝试 ,exec 1>&1exec 2>&2,但没有任何反应。

现在,在不杀死 shell 的情况下,如何分别取回重定向到 stdout 的输出和重定向到 stderr 的错误?文件描述符是引用标准 [in|out]put 和 stderr 的唯一方法吗?

Gil*_*il' 25

运行后exec &>filename,shell 的标准输出和标准错误转至filename. 根据定义,标准输入是文件描述符 0,标准输出是 fd 1,标准错误是 fd 2。

文件描述符既不是重定向的也不是非重定向的:它总是在某个地方(假设进程打开了这个描述符)。重定向文件描述符意味着改变它的去向。运行时exec &>filename,stdout 和 stderr 以前连接到终端,现在连接到filename.

总有一种方法可以引用当前终端:/dev/tty。当一个进程打开这个文件时,它总是意味着进程的控制终端,无论它是什么。因此,如果您想取回该 shell 的原始 stdout 和 stderr,您可以这样做,因为它们所连接的文件仍然存在。

exec &>/dev/tty
Run Code Online (Sandbox Code Playgroud)

  • @ user917279 在处理不同的 Unix 风格方面,它们同样具有便携性。`/dev/tty` 在 `$(tty)` 不起作用的情况下工作:只要进程有一个控制终端,`/dev/tty` 就可以工作(这是你所能希望的最好的,因为必须有仍然将进程与终端连接的东西),而`$(tty)`要求终端仍然在标准输入上打开。 (2认同)

Jos*_* R. 11

你要

exec &>$(tty)
Run Code Online (Sandbox Code Playgroud)

您在问题中所做的是在 stdout 和 stderr 中复制已重定向到文件的原始 stdout 和 stderr 。

正如 Gilles 的回答所解释的,tty将返回当前终端的终端设备。这是默认情况下登录 shell 中三个标准文件描述符的来源/去向。所以上面的语句使用了tty将 stdout 和 stderr 重定向回终端设备,就像以前一样。

如果您担心可移植性(根据您对 Gilles 回答的评论),两种方法(tty 实用程序/dev/ttyfile)都在 POSIX 标准中。

从吉尔斯的评论中逐字复制:

There's an advantage to /dev/tty: it works even after exec <somefile, 
whereas $(tty) would complain “not a tty”
Run Code Online (Sandbox Code Playgroud)

  • `/dev/tty` 有一个优点:即使在 `exec &lt;somefile` 之后它也能工作,而 `$(tty)` 会抱怨“not a tty”。 (3认同)