至于一次重定向大量命令的解决方案:
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee -a $DEBUGLOG
为什么原始解决方案不起作用:exec 2>&1会将标准错误输出重定向到Shell的标准输出,如果您从控制台运行脚本,它将成为控制台。命令上的管道重定向将仅重定向命令的标准输出。
从的角度来看somecommand
,其标准输出进入与之连接的管道tee
,标准错误进入与外壳程序标准错误相同的文件/伪文件中,您可以将其重定向到外壳程序的标准输出,即控制台,如果您从控制台运行程序。
一种真正的解释方式是查看实际发生的情况:
如果从终端运行外壳程序的原始环境,则可能如下所示:
stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42
将标准错误重定向到标准输出(exec 2>&1
)后,您...基本什么都不会更改。但是,如果将脚本的标准输出重定向到文件,则最终会遇到如下环境:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42
然后将shell标准错误重定向到标准输出将最终如下所示:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file
运行命令将继承此环境。如果运行命令并将其通过管道传输到tee,则命令的环境为:
stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file
因此,您的命令的标准错误仍然存在于shell用作其标准错误的地方。
您实际上可以通过查看/proc/[pid]/fd
:ls -l
来查看命令的环境:用于还列出符号链接的内容。0
这里的文件是标准输入,1
是标准输出,2
是标准错误。如果命令打开了更多文件(大多数程序都打开了),您还将看到它们。程序也可以选择重定向或关闭它的标准输入/输出和复用0
,1
和2
。
|&
中2>&1 |
,它充当的快捷方式,至少稍微方便一些。