Как ввести тайм-аут для сценариев оболочки?

Как ввести тайм-аут для сценариев оболочки?

Я хочу запустить скрипт оболочки, в котором есть цикл, и он может продолжаться вечно, чего я не хочу. Поэтому мне нужно ввести тайм-аут для всего скрипта.

Как можно ввести тайм-аут для всего скрипта оболочки в SuSE?

решение1

Если GNU timeoutнедоступен, вы можете использовать его 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'

В конце концов, это будет намного проще, чем писать собственную функцию тайм-аута, которая, как правило, не встроена в оболочки.

решение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'

Связанный контент