
我想運行一個 shell 腳本,其中有一個循環,它可以永遠運行,但我不希望發生這種情況。所以我需要為整個腳本引入一個超時。
如何在 SuSE 下為整個 shell 腳本引入超時?
答案1
如果 GNUtimeout
不可用,您可以使用expect
(Mac OS X、BSD...預設通常沒有 GNU 工具和實用程式)。
################################################################################
# Executes command with a timeout
# Params:
# $1 timeout in seconds
# $2 command
# Returns 1 if timed out 0 otherwise
timeout() {
time=$1
# start the command in a subshell to avoid problem with pipes
# (spawn accepts one command)
command="/bin/sh -c \"$2\""
expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"
if [ $? = 1 ] ; then
echo "Timeout after ${time} seconds"
fi
}
編輯 例子:
timeout 10 "ls ${HOME}"
答案2
謝謝你的澄清。
完成您的任務的最簡單方法是使用包裝器中的循環運行腳本,就像timeout
GNU Coreutils 套件中的命令一樣。
root@coraid-sp:~# timeout --help
Usage: timeout [OPTION] DURATION COMMAND [ARG]...
or: timeout [OPTION]
Start COMMAND, and kill it if still running after DURATION.
Mandatory arguments to long options are mandatory for short options too.
-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 an integer with an optional suffix:
`s' for seconds(the default), `m' for minutes, `h' for hours or `d' for days.
If the command times out, 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. For other processes, it may be necessary to
use the KILL (9) signal, since this signal cannot be caught.
Report timeout bugs to [email protected]
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
For complete documentation, run: info coreutils 'timeout invocation'
最後,這比編寫自己的超時函數要容易得多,而 shell 往往沒有內建超時函數。
答案3
從腳本中啟動一個看門狗進程,以在運行時間過長時殺死其父進程。例子:
# watchdog process
mainpid=$$
(sleep 5; kill $mainpid) &
watchdogpid=$!
# rest of script
while :
do
...stuff...
done
kill $watchdogpid
該腳本將在五秒後被看門狗終止。
答案4
還有cratimeout
作者:馬丁·克拉考爾。
# cf. http://www.cons.org/cracauer/software.html
# usage: cratimeout timeout_in_msec cmd args
cratimeout 5000 sleep 600
cratimeout 5000 tail -f /dev/null
cratimeout 5000 sh -c 'while sleep 1; do date; done'