为什么子进程的状态不为零?

时间:2013-08-27 13:15:02

标签: tcl

考虑以下代码:

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

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

如果子进程出错,它们将在stdout中输出。但是,如果子进程中没有错误,则状态值仍然不为零。怎么避免这个?

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

1 个答案:

答案 0 :(得分:4)

  

如果子进程出错,它们将在stdout中输出。但是如果子进程中没有错误,则状态值仍然不为零。怎么避免这个?

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

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

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

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

如果情况属实,并且您确定该进程不认为出现问题,则必须使用catch解决问题并处理{{3 - 忽略使用已知退出代码退出并传播其他每个错误的进程的情况。

基本上:

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一般的全局变量)描述为extended error information it returns