Bash GNU time返回的信号与打印的信号不同
在运行cronjobs并使用check_mk中的mk job监视其结果时,我偶然发现: 狂欢节: 从Bash GNU time返回的信号与打印的信号不同,bash,time,timeout,exit-code,check-mk,Bash,Time,Timeout,Exit Code,Check Mk,在运行cronjobs并使用check_mk中的mk job监视其结果时,我偶然发现: 狂欢节: 从/usr/bin/time返回的退出代码与写入格式化输出的退出代码不同: time_exit != shell_exit 为什么? 但当使用默认SIGHUP信号时,退出代码匹配: $ /usr/bin/time -f "time_exit: %x" timeout -s SIGHUP 2s sleep 10; echo "shell_exit: $?" C
/usr/bin/time
返回的退出代码与写入格式化输出的退出代码不同:
time_exit != shell_exit
为什么?
但当使用默认SIGHUP信号时,退出代码匹配:
$ /usr/bin/time -f "time_exit: %x" timeout -s SIGHUP 2s sleep 10; echo "shell_exit: $?"
Command exited with non-zero status 124
time_exit: 124
shell_exit: 124
同时,我将使用timeout-k 10s 2s…
,如果进程仍在运行,它将首先发送SIGHUP,并在10s后发送SIGKILL。希望SIGHUP能阻止它
背景
check_mk提供mk job以监视作业执行。mk作业使用时间记录执行时间和退出代码
工时
:
当程序退出、停止或被信号终止时,time命令返回。如果程序正常退出,时间的返回值就是它执行和测量的程序的返回值。否则,返回值为128加上导致程序停止或终止的信号数
人工超时
:
。。。可能需要使用KILL(9)信号,因为无法捕获该信号,在这种情况下,退出状态为128+9而不是124
GNU的%x
只有在进程正常退出时才有意义,而不是被信号终止
[步骤101]$/usr/bin/time-f“%%x=%x”bash-c“退出2”;回显“$?=”$?
命令以非零状态2退出
%x=2
$? = 2.
[步骤102]$/usr/bin/time-f“%%x=%x”bash-c“退出137”;回显“$?=”$?
命令以非零状态退出137
%x=137
$? = 137
[步骤103]$/usr/bin/time-f“%%x=%x”bash-c'kill-kill$$”;回显“$?=”$?
命令被信号9终止
%x=0
$? = 137
[步骤104]$
对于time timeout-s SIGKILL 2s sleep 10
,timeout
通常使用137
退出,它不会被SIGKILL
杀死,就像我的示例中的bash-c'exit 137'
一样
更新: 查看时间的来源,发现无论进程是否正常退出,
%x
都在盲目调用WEXITSTATUS()
655 case 'x': /* Exit status. */
656 fprintf (fp, "%d", WEXITSTATUS (resp->waitstatus));
657 break;
在Git主机中,它添加了新的%Tx
:
549 case 'T':
550 switch (*++fmt)
551 {
...
575 case 'x': /* exit code IF terminated normally */
576 if (WIFEXITED (resp->waitstatus))
577 fprintf (fp, "%d", WEXITSTATUS (resp->waitstatus));
578 break;
从Git主机的时间--help
输出:
。。。
%Tt出口类型(正常/有信号)
%正常退出时的Tx数字退出代码
%Tn数字信号代码(若有信号)
%Ts信号名称(如果有信号)
%如果正常退出且代码为零,则返回“正常”
...
因为时间与超时在同一个进程中运行,超时会自动终止吗?您知道在(子)进程被终止的情况下捕获退出代码的另一种方法吗?对于“使用137退出超时”的情况,timeout
使用137退出,timeout
本身不会被SIGKILL终止,就像我的例子中的bash-c'exit 137'
一样,它意味着time
等待timeout
并获得退出代码137,减去128得到信号9。那么为什么时间本身返回137而打印0呢?我希望time
打印与退出时使用的退出代码相同的退出代码,但time
被终止。正如我在回答中所说,%x
只有在命令正常退出时才有意义<当命令被信号终止时,代码>%x始终为0。这就是时间的设计/实现方式。查看源代码并更新答案。
549 case 'T':
550 switch (*++fmt)
551 {
...
575 case 'x': /* exit code IF terminated normally */
576 if (WIFEXITED (resp->waitstatus))
577 fprintf (fp, "%d", WEXITSTATUS (resp->waitstatus));
578 break;