쉘 스크립팅에 시간 초과를 도입하는 방법은 무엇입니까?

쉘 스크립팅에 시간 초과를 도입하는 방법은 무엇입니까?

나는 루프가 있는 쉘 스크립트를 실행하고 싶지만 원하지 않는 일이 영원히 진행될 수 있습니다. 따라서 전체 스크립트에 대한 시간 제한을 도입해야 합니다.

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

명확하게 해 주셔서 감사합니다.

원하는 작업을 수행하는 가장 쉬운 방법은 timeoutGNU 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

이 스크립트는 5초 후에 감시 장치에 의해 종료됩니다.

답변4

또한 있습니다cratimeout마틴 크라카우어(Martin Cracauer) 지음.

# 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'

관련 정보