众所周知如何将流程的标准输出管道传输到另一个流程标准输入中:
proc1 | proc2
但是如果我想将proc1的标准错误发送到proc2并将标准输出保留到当前位置怎么办?你会认为bash
会有一个命令:
proc1 2| proc2
但是,唉,不。有没有办法做到这一点?
答案 0 :(得分:141)
还有process substitution。这使得一个过程替代了一个文件
您可以按如下方式将stderr
发送到文件:
process1 2> file
但您可以按如下方式替换文件的进程:
process1 2> >(process2)
这是一个将stderr
发送到屏幕并附加到日志文件的具体示例
sh myscript 2> >(tee -a errlog)
答案 1 :(得分:85)
您可以使用以下技巧交换 stdout
和stderr
。然后你只需使用常规管道功能。
( proc1 3>&1 1>&2- 2>&3- ) | proc2
如果stdout
和stderr
两者都指向同一个地方,那么这将为您提供所需的信息。
x>y
位的作用是更改文件句柄x
,因此它现在将其信息发送到文件句柄y
当前指向的位置。对于我们的具体案例:
3>&1
创建一个新句柄3
,它将输出到当前句柄1
(原始标准输出),只是为了保存在下面的最后一个要点。1>&2
修改句柄1
(stdout)以输出到当前句柄2
(原始stderr)。2>&3-
修改句柄2
(stderr)以输出到当前句柄3
(原始标准输出)然后关闭句柄3
(通过最后的-
。它实际上是您在排序算法中看到的交换命令:
temp = value1;
value1 = value2;
value2 = temp;
答案 2 :(得分:64)
Bash 4有这个功能:
如果`|&'使用时,command1的标准错误通过管道连接到command2的标准输入;它是2>& 1 |的简写。在命令指定的任何重定向之后执行标准错误的隐式重定向。
zsh也有此功能。
-
使用其他/旧版shell,只需将其明确输入为
即可FirstCommand 2>& 1 | OtherCommand
答案 3 :(得分:26)
交换非常好,因为它解决了这个问题。如果您甚至不需要原始标准输出,您可以这样做:
proc1 2>&1 1>/dev/null | proc2
订单至关重要;你不会想要:
proc1 >/dev/null 2>&1 | proc1
因为这会将所有内容重定向到/dev/null
!
答案 4 :(得分:0)
这些都不是很好。我发现做自己想要做的最好的方法是:
(command < input > output) 2>&1 | less
这仅在command
不需要键盘输入的情况下有效。例如:
(gzip -d < file.gz > file) 2>&1 | less
可以减少gzip错误