如何在后台运行命令时获取超时退出代码?

如何在后台运行命令时获取超时退出代码?

我正在编写一个 shell 脚本来在后台运行 ping 命令,同时为 ping 命令设置一个超时值,如果 ping 因超时而结束,我想获取退出代码,我使用如下:

timeout 10s ping -c 5 www.google.com | awk '{print "from local to google |", $0;}' &
exit_status=$?
echo $exit_status

但我发现返回的退出代码是“&”,命令在后台运行,而不是超时。

我怎样才能获得超时退出代码?

答案1

这里存在很多问题。第一的,timeout将 a 作为参数单一命令。所以当你写的时候

timeout 10s ping -c 5 www.google.com | awk '{print "from local to google |", $0;}'

发生的事情或多或少是这样的:

( timeout 10s ping -c 5 www.google.com ) | awk '{print "from local to google |", $0;}'

timeout杀死ping,而不是整个管道,因此您会得到管道的退出代码(即 的退出代码awk)。

要获取退出代码,timeout您需要一个子 shell。但由于timeout将单个命令作为参数,因此您需要明确地编写:

timeout 10 sh -c 'ping ... | awk ...' sh

或者,您可以只计算管道中最后一个命令的时间(即awk):

ping ... | timeout 10 awk ...

这对于 应该可以正常工作ping | awk,但对于其他命令来说可能容易出现竞争条件。如果ping产生大量输出,您可能还会收到 SIGPIPE,用于杀死侦听器。

回到你的问题,你还想把所有这些放在后台。要获取后台命令的退出代码,您需要wait

timeout 10 sh -c 'ping ... | awk ...' sh &
wait $!
echo $?

遗憾的bash是没有异步wait,这违背了在后台运行命令的目的。不过,您可以在此之前运行其他命令wait

相关内容