我必须处理一个编译器,它有时会输出一个伪错误。我不希望在这种情况下停止我的构建过程。相反,我只想忽略错误并重新运行编译器:

%o: %c
    $(prefix) dumb_compiler -c $^ -o $@ $(suffix)

我的目标是定义$prefix$suffix来忽略伪错误。让我们简单地考虑一下这个虚拟程序,而不是dumb_compiler
#!/usr/bin/perl
my $i = int rand 10;
die "Error -42\n" if $i > 5;
die "Error -12\n" if $i % 2;
print "$i\n";

Error -42发生时,我想放弃stdoutstderr并再次运行程序,就像什么都没发生一样。在其他情况下,我想打印程序将要打印的内容。
我想在bash中以一行代码的形式编写以下内容,以便将其放入Makefile配方中:
while True:
    (_exit, _stdout, _stderr) = exec(program)
    if _exit == 0 and "Error -42" not in _stderr:
        print(stdout=_stdout, stderr=_stderr)
        exit(_exit)

我现在写了这个,但它不起作用,看起来不像一个单行程序
#!/usr/bin/bash
exit_status=0
run=1
exec 3>&1
exec 4>&2
while [ $run -eq 1 ];
do
    run=0
    ./program 2>&4 1>&3
    $exit_status=$?
    if [ $exit_status -ne 0 ]
    then
        &4 > grep -q "Error -42"
        if [ $? -ne 0 ]:
        then
            run=1
        fi
    fi
done
3>&1
4>&2
3>&-
4>&-
exit $exit_status

我的问题是我如何正确地保持STDUT、STDRR和退出状态从我的程序执行,并冲洗出来后,我完成了吗?
我仍然可以试着让我的程序工作,但我认为我的方法是错误的,这就是为什么我宁愿这样问。

最佳答案

用文件就行了。重定向到其他文件句柄不会缓冲任何内容(在内存或磁盘上);它们不是这里的解决方案。

while true; do
   ./program > /tmp/output 2> /tmp/error && break
   exit_status=$?
   grep -q "Error -42" /tmp/error || break
done
cat /tmp/output
cat /tmp/error >&2
exit $exit_status

这样做的一个小缺点是标准输出和标准错误不会交错,但这不应该是一个很大的损失。只有当它们都写入同一个文件句柄时,它们才被“正确”交错;一旦将它们分开(如果只想在标准错误中查找Error -42,则需要这样做),就失去了保留原始程序生成它们的相对顺序的能力。

关于bash - 如何捕获stdout,stderr和$?暂时in,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42705001/

10-11 02:54