使用bash,如何将标准错误导入另一个进程?

使用bash,如何将标准错误导入另一个进程?,bash,pipe,stderr,Bash,Pipe,Stderr,众所周知,如何将一个流程的标准输出导入另一个流程的标准输入: proc1 | proc2 但是,如果我想将proc1的标准错误发送到proc2,并将标准输出保留到其当前位置,该怎么办?您可能会认为bash会有一个大致如下的命令: proc1 2| proc2 但是,唉,没有。有什么方法可以做到这一点吗?您可以使用以下技巧来交换stdout和stderr。然后您只需使用常规管道功能 ( proc1 3>&1 1>&2- 2>&3- ) | proc2

众所周知,如何将一个流程的标准输出导入另一个流程的标准输入:

proc1 | proc2
但是,如果我想将proc1的标准错误发送到proc2,并将标准输出保留到其当前位置,该怎么办?您可能会认为
bash
会有一个大致如下的命令:

proc1 2| proc2

但是,唉,没有。有什么方法可以做到这一点吗?

您可以使用以下技巧来交换
stdout
stderr
。然后您只需使用常规管道功能

( proc1 3>&1 1>&2- 2>&3- ) | proc2
如果
stdout
stderr
在开始时都指向同一个位置,这将为您提供所需的内容

x>y
位所做的是更改文件句柄
x
,因此它现在将其信息发送到文件句柄
y
当前指向的位置。对于我们的具体案例:

  • 3>&1
    创建一个新句柄
    3
    ,该句柄将输出到当前句柄
    1
    (原始stdout),只需将其保存在某个地方,以供下面的最后一个要点使用
  • 1>&2
    修改句柄
    1
    (标准输出)以输出到当前句柄
    2
    (原始标准输出)
  • 2>&3-
    修改句柄
    2
    (stderr)以输出到当前句柄
    3
    (原始stdout),然后关闭句柄
    3
    (通过末尾的
    -
它实际上是您在排序算法中看到的swap命令:

temp   = value1;
value1 = value2;
value2 = temp;

Bash 4具有以下功能:

如果使用`&',则command1的标准错误通过管道连接到command2的标准输入;它是2>和1的简写。标准错误的隐式重定向是在命令指定的任何重定向之后执行的

zsh也有这个特性

--

对于其他/旧的shell,只需显式输入


FirstCommand 2>&1 | OtherCommand

交换很好,因为它解决了问题。如果您甚至不需要原始标准输出,您可以这样做:

proc1 2>&1 1>/dev/null | proc2
秩序至关重要;你不会想要:

proc1 >/dev/null 2>&1 | proc1
因为这会将所有内容重定向到
/dev/null

还有。它使一个进程代替一个文件。
您可以按如下方式将
stderr
发送到文件:

process1 2> file
process1 2> >(process2)
但您可以按如下方式替换文件的进程:

process1 2> file
process1 2> >(process2)
下面是一个将
stderr
发送到屏幕并附加到日志文件的具体示例

sh myscript 2> >(tee -a errlog)

这些都不是很有效。我发现做你想做的事情的最好方法是:

(command < input > output) 2>&1 | less

通过读取文档,可以将gzip错误减少到,这会产生标准错误和输出,而不仅仅是stderr,但是很高兴知道。我想是时候开始研究bash 4了。当前的bash手册上写着“如果使用了|&命令的标准错误,除了它的标准输出外,还连接到command2的标准输入”。这显然不是OP想要的。@PeterA.Schneider:OP说“将标准输出保留到其当前位置”,这可能是不明确的。我没有看到任何不明确的地方。你的建议(1)将这两种观点混为一谈。(2)
OtherCommand
将组合数据写入某个地方,可能是其他地方。所以它不是相同的数据,而且它可能会转移到其他地方。这与OP的愿望正好相反,不是吗?@PeterA.Schneider:standard output的当前位置在哪里?如果
proc1
输出到stdout和stderr,并且您希望stderr转到
proc2
的stdin(这就是proc1的stdout要去的地方),那么我的回答就完成了。我给了OP他想要的,也许不是他想要的。这就是潜在的模糊性。OP接受了交换stdout和stderr的答案,这不是他想要的。在这里使用
1>&2-
而不仅仅是
1>&2
有什么价值?我不明白为什么我们要关闭fd
2
,如果我们要立即重新打开/重新分配它。@可疑的Jim,在那种情况下没有优势,我怀疑我这样做只是为了保持一致性-关闭文件句柄3是释放它的好主意。好主意,@ovgolovin,真不敢相信,自从我做了那次编辑后,七个月内竟然没有人注意到这一点。按照您的建议修复。尝试让gcc的make(在我的系统上着色)使用此“(make 3>&1 1>&2-2>&3-)| less-R”而“(ls-al 3>&1>&2-2>&3-| less-R”按预期工作。对于第二个重定向,您的解释似乎回到了前面。1> &2-将文件句柄2(原始stderr)设置为句柄1(原始stdout)2>&3-将文件句柄3(复制的stdout)设置为句柄2(原始stderr)。如果我错了,请纠正我。顺便说一句,我猜2上的破折号是为了防止新的stderr数据在填充来自stdout的数据时被发送到此缓冲区。这正确地回答了所述的问题,并且应该是@paxdiabloI尝试的接受答案。它不起作用(
weston--help 2>>(less)
),它打破了我的外壳,我不得不退出并重新登录。@Rolf如果
weston--help
less
都希望有键盘交互,但只有一个收到,那么你可能会处于尴尬的境地。试着用
grep
之类的工具来做测试。另外,您可能会发现,两个鼠标/键盘输入都将转到第二个命令,而不是weston。如果您想使用
|&
重定向stderr和stdout,我从中了解到,您可以在
rc
中执行如此简单的重定向,这是另一个shell。例如:
proc1 |[2]proc2
。这不是很好吗?但不在bash中。相关:。最简单的管道解决方案是stdout和stderr。