Bash GNU time返回的信号与打印的信号不同

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

在运行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: $?"
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;