您的位置:首页 > 运维架构 > Shell

设置Linux命令或者shell脚本的运行时间限制

2017-08-17 22:16 871 查看
有些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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息