在脚本中,错误通常用 发送到文件描述符 2 &2
,即:
echo "error" >&2
有时/dev/stderr
也用:
echo "error" > /dev/stderr
查看/dev/stderr
,我发现它只是 的符号链接,而 又是(在我当前的终端上)/proc/self/fd/2
的符号链接。/dev/pts/5
似乎有点过于复杂。这背后有什么逻辑吗?
使用/dev/stderr
和&2
等价吗?
其中任何一个比另一个更受青睐吗?
答案1
特殊设备/dev/stderr
是系统特定的,而文件描述符2
(不是特殊设备/proc/self/fd/2
)是可移植的。如果您想编写不可移植的代码,这些特殊设备是一个很好的起点。
有一些系统带有/dev/stderr
:当然是 Linux,以及操作系统X。但 OSX 没有/proc
文件系统,它/dev/stderr
是一个到/dev/fd/2
.
进一步阅读:
- “> /dev/stdout”的可移植性
- 我应该使用什么方法在 bash 脚本中使用“printf”将错误消息写入“stderr”?
- 补丁/awk-dev-stderr(autoconf 补丁)
- 在 Bash 脚本中重定向 stderr 和 stdout
- 第 20 章 I/O 重定向(高级 Bash 脚本编写指南)
答案2
在 bash 和其他 shell 中,重定向某些内容的方法到标准错误是使用>&2
. Bash 打开/dev/stderr
为文件描述符 2
。文件描述符通过描述符编号&N
来引用。N
因此,echo error >&2
将打印error
到标准错误,到/dev/stderr
.
它还将/dev/stdout
作为文件描述符打开1
。这意味着你可以做到echo output >&1
。但是,由于默认情况下所有内容都会打印到标准输出,因此它echo output
本身是相同的。
现在,2>
不同了。在这里,您将命令的错误输出重定向到其他地方。因此,2>file
意味着“将打印到文件描述符 2(标准错误)的任何内容重定向到file
”。
答案3
你说得对,>&2
更直接、更“惯用”。它们应该是等效的,因此没有特殊的理由使用>/dev/stderr
.除此之外,如果阅读的人不知道它们的作用,其中一个可能比另一个更容易找到:-)。但一般来说我建议你使用>&2
.
当程序将错误写入指定文件名但不支持 stderr 时,/dev/stderr 可能很有用。显然这有点做作; /dev/stdout 更有用。 (我最近发现mysql_safe
包装器脚本不会将错误写入控制台;不幸的是它还想更改错误日志文件的权限,因此使用 /dev/stderr 会导致一些多余的警告)。