我遇到过几个使用2>&1
和的命令1>&2
,但我完全不明白使用它的目的以及何时应该使用它。
我的理解
我知道1
代表标准输出,2
代表标准错误。我理解结合了的2>&1
输出,反之亦然。2
1
我不明白的是
- 我应该什么时候使用它?
- 它有什么用途?
答案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 和其他一些程序提供——但在这里它是在没有任何外部依赖的情况下实现的。