众所周知,如何将一个流程的标准输出导入另一个流程的标准输入:
proc1 | proc2
但是,如果我想将 proc1的标准错误发送到 proc2,并将标准输出保留到其当前位置,那么该怎么办呢?你可能会认为 bash的命令大致如下:
bash
proc1 2| proc2
但是,唉,没有。有什么办法可以做到这一点吗?
您可以使用下面的技巧 交换 stdout和 stderr。然后您只需使用常规的管道功能。
stdout
stderr
( proc1 3>&1 1>&2- 2>&3- ) | proc2
如果 stdout和 stderr在开始时都指向同一个位置,这将给你你所需要的。
x>&y位所做的是更改文件句柄 x,因此它现在将其数据发送到文件句柄 y当前指向的任何位置。针对我们的具体案例:
x>&y
x
y
3>&1
3
1
1>&2
2
2>&3-
-
它实际上就是排序算法中的交换命令:
temp = value1; value1 = value2; value2 = temp;
Bash 4有这样一个特性:
如果使用“ | &”,command1的标准错误将通过管道连接到 command2的标准输入; 它是2 > & 1 | 的简写。这个标准错误的隐式重定向是在命令指定的任何重定向之后执行的。
Zsh 也有这个特性。
--
对于其他/旧的 shell,只需显式输入以下内容
FirstCommand 2 > & 1 | OtherCommand 第一命令2 > & 1 | 其他命令
交换是伟大的,因为它解决了问题。为了以防万一,你甚至不需要原始的标准输出,你可以这样做:
proc1 2>&1 1>/dev/null | proc2
命令是至关重要的,你不会想要:
proc1 >/dev/null 2>&1 | proc1
因为这将重定向到 /dev/null的一切!
/dev/null
也有 工序替代工序替代。它使一个进程替代文件。 您可以将 stderr发送到以下文件:
process1 2> file
但是您可以用一个进程替换文件,如下所示:
process1 2> >(process2)
下面是一个将 stderr发送到屏幕并附加到日志文件的具体示例
sh myscript 2> >(tee -a errlog)
我发现做你想做的事情的最好方法是:
(command < input > output) 2>&1 | less
这只适用于 command不需要键盘输入的情况。例如:
command
(gzip -d < file.gz > file) 2>&1 | less
会减少 gzip 错误