有些shell脚本或者命令,只有在规定时间内运行完成才有意义,这时可以设置脚本/命令的时间限制,如果在设定时间内,还没有完成,则终止命令/脚本。可以使用timeout命令来做到,先看一下它的用法:
$ man timeout
TIMEOUT(1) User Commands TIMEOUT(1)
NAME
timeout - run a command with a time limit
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
DESCRIPTION
Start COMMAND, and kill it if still running after DURATION.
Mandatory arguments to long options are mandatory for short options too.
--preserve-status
exit with the same status as COMMAND, even when the command times out
--foreground
When not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and receive
TTY signals. In this mode, children of COMMAND will not be timed out.
-k, --kill-after=DURATION
also send a KILL signal if COMMAND is still running this long after the initial signal was sent.
-s, --signal=SIGNAL
specify the signal to be sent on timeout. SIGNAL may be a name like 'HUP' or a number. See 'kill -l'
for a list of signals
--help
display this help and exit
--version
output version information and exit
DURATION is a floating point number with an optional suffix: 's' for seconds (the default), 'm' for minutes,
'h' for hours or 'd' for days.
If the command times out, and --preserve-status is not set, then exit with status 124. Otherwise, exit with
the status of COMMAND. If no signal is specified, send the TERM signal upon timeout. The TERM signal kills
any process that does not block or catch that signal. It may be necessary to use the KILL (9) signal, since
this signal cannot be caught, in which case the exit status is 128+9 rather than 124.
BUGS
Some platforms don't curently support timeouts beyond 2038
AUTHOR
Written by Padraig Brady.
REPORTING BUGS
Report timeout bugs to bug-coreutils@gnu.org
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
Report timeout translation bugs to <http://translationproject.org/team/>
COPYRIGHT
Copyright 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent per鈥[m
mitted by law.
SEE ALSO
kill(1)
The full documentation for timeout is maintained as a Texinfo manual. If the info and timeout programs are
properly installed at your site, the command
info coreutils 'timeout invocation'
should give you access to the complete manual.
GNU coreutils 8.21 March 2016 TIMEOUT(1)
示例1,假设有如下脚本,每隔一秒钟输出一次系统时间
qingsong@db2a:~$ cat infiniteloop.sh
#!/bin/bash
while true
do
echo -n "Current date: "
date
sleep 1
done
qingsong@db2a:~$ bash infiniteloop.sh
Current date: Thu Aug 17 02:48:15 PDT 2017
Current date: Thu Aug 17 02:48:16 PDT 2017
Current date: Thu Aug 17 02:48:17 PDT 2017
Current date: Thu Aug 17 02:48:18 PDT 2017
Current date: Thu Aug 17 02:48:19 PDT 2017
Current date: Thu Aug 17 02:48:20 PDT 2017
Current date: Thu Aug 17 02:48:21 PDT 2017
Current date: Thu Aug 17 02:48:22 PDT 2017
Current date: Thu Aug 17 02:48:23 PDT 2017
^C <---Ctrl+c手动终止
可以看到,上面的脚本只有ctrl+c才会终止,否则会永远运行,现在可以使用timeout,设置超时限制为3秒钟:
qingsong@db2a:~$ timeout 3 bash infiniteloop.sh
Current date: Thu Aug 17 02:48:35 PDT 2017
Current date: Thu Aug 17 02:48:36 PDT 2017
Current date: Thu Aug 17 02:48:37 PDT 2017
qingsong@db2a:~$
示例2,timeout命令还可以发送信号,具体怎么处理信号,由程序或者shell本身决定。下面的脚本中,对于SIGINT信号的处理方式仅仅是打印一条信息
qingsong@db2a:~$ cat infiniteloop.sh
#!/bin/bash
trap "echo received a interrupt signal" SIGINT
while true
do
echo -n "Current date: "
date
sleep 1
done
timeout命令在3s后向脚本发出一个SIGINT信号:
qingsong@db2a:~$ timeout -s SIGINT 3 bash infiniteloop.sh
Current date: Thu Aug 17 03:41:09 PDT 2017
Current date: Thu Aug 17 03:41:10 PDT 2017
Current date: Thu Aug 17 03:41:11 PDT 2017
received a interrupt signal <--捕捉到由timeout发出的信号
Current date: Thu Aug 17 03:41:12 PDT 2017
Current date: Thu Aug 17 03:41:13 PDT 2017
Current date: Thu Aug 17 03:41:14 PDT 2017
^Creceived a interrupt signal <---Ctrl+c手动终止
Current date: Thu Aug 17 03:41:14 PDT 2017
Current date: Thu Aug 17 03:41:15 PDT 2017
^Creceived a interrupt signal <---Ctrl+c手动终止
Current date: Thu Aug 17 03:41:16 PDT 2017
Current date: Thu Aug 17 03:41:17 PDT 2017
^Z <--手动地ctrl+z
[1]+ Stopped timeout -s SIGINT 3 bash infiniteloop.sh
qingsong@db2a:~$ jobs
[1]+ Stopped timeout -s SIGINT 3 bash infiniteloop.sh
qingsong@db2a:~$ ps -ef | grep -i infiniteloop.sh
qingsong 52631 46284 0 03:41 pts/5 00:00:00 timeout -s SIGINT 3 bash infiniteloop.sh
qingsong 52632 52631 0 03:41 pts/5 00:00:00 bash infiniteloop.sh
qingsong 52690 46284 0 03:41 pts/5 00:00:00 grep --color=auto -i infiniteloop.sh
qingsong@db2a:~$ kill -9 52631