timeout是一个命令行工具,它运行一个指定的命令,如果在给定的时间后仍在运行,则终止该命令。换句话说,timeout命令允许你运行一个有时间限制的命令。timeout命令是GNU核心实用程序包的一部分(GNU core utilities package),几乎所有的Linux发行版都安装了该包。

当你想运行一个没有内置超时选项的命令时,它就很方便。

在这篇文章中,我们将解释如何使用Linux超时命令。

如何使用timeout命令

timeout命令的语法如下。

timeout [OPTIONS] DURATION COMMAND [ARG]...
DURATION可以是一个正整数或一个浮点数,后面是一个可选的单位后缀。
* s - seconds (default)
* m - minutes
* h - hours
* d - days

当没有使用单位时,默认为秒。如果持续时间(Duration)被设置为零,则此命令不起作用。

下面是几个基本的例子,演示了如何使用timeout命令:

五秒后终止命令:

$ timeout 5 ping 8.8.8.8
五分钟后终止一个命令:
$ timeout 5m ping 8.8.8.8
在1分6秒后终止一个命令:
$ timeout 1.1m ping 8.8.8.8
如果你想运行一个tcpdump命令,需要提高权限,要在timeout命令前加上 sudo :
$ sudo timeout 300 tcpdump -n -w data.cap
发送指定信号 / Sending Specific Signal
如果不使用信号选项,timeout在达到时间限制时向被启动的命令发送SIGTERM信号。你可以使用-s(--signal)选项指定要发送的信号。
例如,要在一分钟后向ping命令发送SIGKILL,你可以使用:
$ sudo timeout -s SIGKILL ping 8.8.8.8
你可以用名字指定信号,如SIGKILL,或者使用信号的数字值,如9。 下面的命令与前面的命令相同:
$ sudo timeout -s 9 ping 8.8.8.8

要获得所有可用信号的列表,使用kill -l命令:

$ kill -l

杀死卡住的进程 / Killing Stuck Processes

SIGTERM,当超过时间限制时发送的默认信号,可能被一些进程捕获或忽略。在这些情况下,进程在终止信号(termination signal)发出后继续运行。

为了确保能杀掉被监视的命令,可以使用-k(--kill-after)选项,后面加一个时间段,long option可以--kill-after=DURATION。当使用这个选项后,在达到给定的时间限制后,timeout命令会向被监控的程序发送SIGKILL信号,该信号不能被捕捉或忽略。

在下面的例子中,timeout命令等待ping命令运行一分钟后,发送终止信号。如果ping命令还在运行,将在十秒钟后发送kill信号,强制杀掉该进程:

$ sudo timeout -k 10 1m ping 8.8.8.8

如果使用kill信号杀死进程,那timeout命令返回的exit status就不是124,而是128+9了。

保存退出状态 / Preserving the Exit Status

timeout启动的命令运行达到限时后,timeout命令返回124。否则,它会返回被监视命令的退出状态(exit status)。

要想在达到时限时仍然返回命令的退出状态,请使用 --preserve-status 选项:

$ timeout --preserve-status 5 ping 8.8.8.8
举例:
$ sleep 2
$ echo $?
0
$ timeout 2 sleep 1
$ echo $?
0
$ timeout 1 sleep 3
$ echo $?
124
$ timeout --preserve-status 1 sleep 3
$ echo $?
143
$  timeout --preserve-status 5 ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
$ echo $?
143
$  timeout  2 ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
$ echo $?
124

在前台运行 / Running in Foreground

默认情况下,timeout在后台运行所监控的命令。如果你想在前台运行命令,请使用 --foreground 选项。

timeout --foreground 5m ./script.sh

当你想运行一个需要用户输入的交互式命令时,这个选项很有用。

其他选项

可以使用-v或--verbose选项,会显示出具体的操作信息,比如:

$ timeout -v 3 ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

timeout: sending signal TERM to command ‘ping’

还有--help和--verion选项,是通用的。

结论/Conclusion

timeout命令用于运行一个有时间限制的命令。

timeout是一个简单的命令,没有太多的选项。通常情况下,你只用两个参数来调用timeout,即持续时间和被启动和监控的命令。