为什么将输出重定向到 2>&1 和 1>&2?

为什么将输出重定向到 2>&1 和 1>&2?

我遇到过几个使用2>&1和的命令1>&2,但我完全不明白使用它的目的以及何时应该使用它。

我的理解

我知道1代表标准输出,2代表标准错误。我理解结合了的2>&1输出,反之亦然。21

我不明白的是

  1. 我应该什么时候使用它?
  2. 它有什么用途?

答案1

有时你想重定向标准输出stderr 到相同的位置,这是>&使用时 - 它将一个文件描述符指向另一个文件描述符。


例如,如果你想将 stdout 和 stderr 写入同一个文件(无论是/dev/null还是output.txt),你可以分别重定向它们,使用

app 1>/dev/null 2>/dev/null

或者你可以将一个文件描述符重定向到该文件,并将另一个文件描述符重定向到第一个文件:

app 1>/dev/null 2>&1

app 2>/dev/null 1>&2

在第一个示例中,2>&1将文件描述符 #2 指向 #1 已经指向的位置。第二个示例实现了相同的功能,只是从 stderr 开始。

再举一个例子,有些情况下 stdout(文件描述符 #1)已经指向所需位置,但您无法通过名称引用它(它可能与管道、套接字等相关联)。这通常在使用进程扩展(或运算符` `)时发生$( ),进程扩展通常只捕获 stdout,但您可能希望将 stderr 包含在内。在这种情况下,您还可以使用>&将 stderr 指向 stdout:

out=$(app 2>&1)

另一个常见的例子是分页器grep或类似的实用程序,因为管道|通常仅在 stdout 上工作,所以您可以在使用管道之前将 stderr 重定向到 stdout:

app 2>&1 | grep hello

如何知道2>&1或哪一个1>&2是正确的?已经设置文件描述符位于 的右侧>&,而要重定向的文件描述符位于 的左侧。(2>&1意思是“将文件描述符 #2 指向文件描述符 #1”)。


一些 shell 具有常见重定向的快捷方式;以下是 Bash 的示例:

  • 1>可以缩短为>

  • 1>foo 2>&1>&foo&>foo

  • 2>&1 | program|& program

答案2

当你想strace在分页器中显示输出时,你会需要它。strace将其输出打印到标准错误和管道通常连接标准输出到标准输入,因此您必须使用重定向:

strace -p $pid 2>&1 | less

答案3

有时,您希望将stdout( 1) 和stderr( 2) 重定向到同一位置 ( /dev/null,例如 )。实现此目的的一种方法是:

$ program 1>/dev/null 2>/dev/null

但大多数人通过重定向到stderr以下stdout方式来缩短此过程2>&1

$ program 1>/dev/null 2>&1

更短的版本是:

$ program >&- 2>&-

答案4

我用它来开始一项独立的工作:

someProgram 2>&1 >& my.log &

然后我可以注销,而一些程序仍会运行。该功能由 GNU Screen、tmux 和其他一些程序提供——但在这里它是在没有任何外部依赖的情况下实现的。

相关内容