在脚本的早期,我看到了这个:
exec 3>&2
之后:
{ $app $conf_file &>$app_log_file & } 1>&3 2>&1
我对此的理解是这样的:
- 创建 fd
3
- 重定向 fd
3
输出到stderr
- (在应用程序执行时)将
stdout
重定向到 fd3
,然后将stderr
重定向到stdout
这不是某种疯狂的循环吗? 3
stderr
stdout
3
>等?
我特别关心这一行的意图/含义,因为我想开始使用这个脚本和 valgrind
运行一些应用程序。我希望看到 valgrind
的输出散布在应用程序的日志语句中,因此我希望 stderr
的默认输出被上面令人困惑的行捕获。然而,在导致我想使用 valgrind
的一些崩溃中,我看到 glibc 错误直接输出到终端,而不是在应用程序的日志文件中捕获。
那么,问题是:那条执行线到底做了什么?它是否捕获 stderr
?如果是这样,为什么我在应用程序崩溃时会在命令行上看到 glibc 输出?如果不是,我应该如何改变它来实现这个目标?
最佳答案
您误读了 3>&2
语法。这意味着打开 fd 3 并使其成为 fd 2 的副本。参见 Duplicating File Descriptors .
以同样的方式,2>&1
不意味着使 fd 2 指向 fd 1 的位置它意味着重新打开 fd 2 作为 fd 1 的副本(主要是相同的净效果,但语义不同)。
还要记住,所有的重定向都是在它们发生的时候发生的,这里没有“指针”。所以 2>&1 1>/dev/null
不会 将标准错误重定向到 /dev/null
它会将标准错误附加到任何标准输出已附加到(可能是终端)。
所以有问题的代码是这样做的:
- 打开 fd 3 作为 fd 2 的副本
- 重新打开 fd 1 作为 fd 3 的副本
- 重新打开 fd 2 作为 fd 1 的副本
实际上,这些行将所有内容发送到标准错误(或在初始 exec
行运行时附加 fd 2 的任何地方)。如果重定向是 2>&1 1>&3
那么它们就会交换位置。我想知道这是否是该行的初衷,因为正如所写的那样,它毫无意义。
更不用说大括号列表内部的重定向,大括号列表外部的重定向是相当无用的。
关于linux - Bash:多重重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31301153/