考虑以下代码:
set status [catch {eval exec $Executable $options | grep "(ERROR_|WARNING)*" >@ stdout} errorMessage]
if { $status != 0 } {
return -code error ""
}
如果子进程出错,它们将在stdout中输出。但是,如果子进程中没有错误,则状态值仍然不为零。怎么避免这个?
还有一些方法可以使用fileutil::grep
代替bash grep吗?
答案 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。