我们都知道如何将一个进程的标准输出导入另一个进程的标准输入:
proc1 | proc2
但是如果我想将proc1的标准错误发送到proc2,同时保留标准输出流到当前位置怎么办?你可能会认为有一个类似以下命令的指令:
proc1 2| proc2
但是,唉,没有。有什么办法可以做到这一点吗?
还有进程替换的方法,可以将进程替换为文件。
您可以按如下方式将stderr
发送到文件:
process1 2> file
但是你可以按照以下步骤,用进程替代文件:
process1 2> >(process2)
这里有一个具体的例子,将stderr
发送到屏幕并追加到日志文件中。
sh myscript 2> >(tee -a errlog)
weston --help 2> >(less)
),但它没有起作用,反而破坏了我的shell,我不得不退出并重新登录。 - Rolfweston --help
和 less
都期望有键盘交互,但只有其中一个接收到了输入,那么你可能会陷入尴尬的境地。尝试使用类似 grep
的东西进行测试。此外,你可能会发现鼠标/键盘输入都被发送到第二个命令,而不是 weston。 - BeowulfNode42stdout
和stderr
。然后您只需使用常规的管道功能。( proc1 3>&1 1>&2- 2>&3- ) | proc2
如果在开始时提供的stdout
和stderr
都指向同一个位置,那么这将为您提供所需的结果。
x>&y
的作用是更改文件句柄x
,使其现在将数据发送到文件句柄y
当前所指向的位置。对于我们的特定情况:
3>&1
创建一个新的句柄3
,它将输出到当前的句柄1
(原始的stdout),只是为了将其保存在下面的最后一条记录中。1>&2
修改句柄1
(stdout)以输出到当前的句柄2
(原始的stderr)。2>&3-
修改句柄2
(stderr)以输出到当前的句柄3
(原始的stdout),然后通过结尾处的-
关闭句柄3
。它实际上就像你在排序算法中看到的交换命令一样:
temp = value1;
value1 = value2;
value2 = temp;
1>&2-
相比于仅使用1>&2
的价值是什么?如果我们只是立即重新打开/重新分配它,我不理解为什么要关闭fd 2
。 - dubiousjimBash 4有这个功能:
如果使用 `|&',则通过管道将command1的标准错误连接到command2的标准输入;它是2>&1 |的简写。此标准错误的隐式重定向在命令指定的任何重定向之后执行。
zsh也具有此功能。
--
在其他/旧的shell中,只需明确输入以下内容:
FirstCommand 2>&1 | OtherCommand
OtherCommand
在某个地方写入 合并后 的数据,可能是其他地方。因此,它不是相同的数据,并且可能被传输到其他地方。这与 OP 的期望正好相反,对吗? - Peter - Reinstate Monicaproc1
输出到stdout和stderr,并且您希望将stderr发送到proc2
的stdin(这是proc1的stdout所在的位置),那么我的答案就可以实现。我给了OP他所“要求”的,也许不是他“想要”问的。其中存在潜在的歧义。OP接受了交换stdout和stderr的答案,这不是他要求的。 - Dennis Williamson交换是很好的,因为它解决了问题。如果您甚至不需要原始的标准输出,您可以这样做:
proc1 2>&1 1>/dev/null | proc2
顺序非常重要;你不希望:
proc1 >/dev/null 2>&1 | proc1
由于这将把所有内容都重定向到 /dev/null
!
这些方法都不是很有效。我找到的最好的方法是:
(command < input > output) 2>&1 | less
这仅适用于command
不需要键盘输入的情况,例如:
(gzip -d < file.gz > file) 2>&1 | less
将gzip错误放入less中
rc
中进行这样简单的重定向,它是另一个shell。例如:proc1 |[2] proc2
。很不错吧? 但在bash
中不行。 - Rolf