0

考虑这段代码:

set status [catch {eval exec $Executable $options | grep "(ERROR_|WARNING)*" >@ stdout}  errorMessage] 

if { $status != 0 }  {
    return -code error ""
} 

如果子进程出现错误,它们会在标准输出中输出。但是如果子进程没有错误,状态值仍然非零。如何避免这种情况?

还有一些方法可以fileutil::grep代替 bash grep 吗?

4

1 回答 1

4

如果子进程出现错误,它们会在标准输出中输出。但是如果子进程没有错误,状态值仍然非零。如何避免这种情况?

向任何文件描述符(包括连接到“标准错误流”的文件描述符)写入内容和返回非零退出代码之间没有任何联系,因为就操作系统而言,这些概念是完全独立的。进程可以完全不执行任何 I/O 并返回非零退出代码(对于 Unix 守护进程来说这是一种常见的情况,它记录所有内容,包括错误,通过syslog),或者将某些内容写入其标准错误流并返回退出时为零 - 软件将某些有价值的数据写入它们stdout并在请求时向它们提供诊断消息的常见情况stderr

因此,首先验证您的进程没有向其标准错误写入任何内容,并且仍然使用纯 shell 以非零退出代码退出

$ that_process --its --command-line-options and arguments if any >/dev/null
$ echo $?

(该过程应该不打印任何内容,并且echo $?应该打印一个非零数字)。

如果情况属实,并且您确定进程不认为有问题,您将不得不使用catch并处理它返回的扩展错误信息来解决它- 忽略进程以已知退出代码退出的情况并传播所有其他错误。

基本上:

set rc [catch {exec ...} out]
if {$rc != 0} {
    global errorCode errorInfo
    if {[lindex $errorCode 0] ne "CHILDSTATUS"} {
        # The error has nothing to do with non-zero process exit code
        # (for instance, the program wasn't found or the current user
        # did not have the necessary permissions etc), so pass it up:
        return -code $rc -errorcode $errorCode -errorinfo $errorInfo $out
    }
    set exitcode [lindex $errorCode 2]
    if {$exitcode != $known_exit_code} {
        # Unknown exit code, propagate the error:
        return -code $rc -errorcode $errorCode -errorinfo $errorInfo $out
    }
    # OK, do nothing as it has been a known exit code...
}

CHILDSTATUS(以及errorCode一般的全局变量)在此处进行了描述。

于 2013-08-27T14:29:27.023 回答