How do I limit the running time of a BASH script

前端 未结 5 1634
慢半拍i
慢半拍i 2020-12-01 14:39

I have a long running BASH script that I am running under CYGWIN on Windows.

I would like to limit the script to run for 30 seconds, and automatically terminate if i

5条回答
  •  再見小時候
    2020-12-01 15:12

    The following script shows how to do this using background tasks. The first section kills a 60-second process after the 10-second limit. The second attempts to kill a process that's already exited. Keep in mind that, if you set your timeout really high, the process IDs may roll over and you'll kill the wrong process but this is more of a theoretical issue - the timeout would have to be very large and you would have to be starting a lot of processes.

    #!/usr/bin/bash
    
    sleep 60 &
    pid=$!
    sleep 10
    kill -9 $pid
    
    sleep 3 &
    pid=$!
    sleep 10
    kill -9 $pid
    

    Here's the output on my Cygwin box:

    $ ./limit10
    ./limit10: line 9:  4492 Killed sleep 60
    ./limit10: line 11: kill: (4560) - No such process
    

    If you want to only wait until the process has finished, you need to enter a loop and check. This is slightly less accurate since sleep 1 and the other commands will actually take more than one second (but not much more). Use this script to replace the second section above (the "echo $proc" and "date" commands are for debugging, I wouldn't expect to have them in the final solution).

    #!/usr/bin/bash
    
    date
    sleep 3 &
    pid=$!
    ((lim = 10))
    while [[ $lim -gt 0 ]] ; do
        sleep 1
        proc=$(ps -ef | awk -v pid=$pid '$2==pid{print}{}')
        echo $proc
        ((lim = lim - 1))
        if [[ -z "$proc" ]] ; then
                ((lim = -9))
        fi
    done
    date
    if [[ $lim -gt -9 ]] ; then
        kill -9 $pid
    fi
    date
    

    It basically loops, checking if the process is still running every second. If not, it exits the loop with a special value to not try and kill the child. Otherwise it times out and does kill the child.

    Here's the output for a sleep 3:

    Mon Feb  9 11:10:37 WADT 2009
    pax 4268 2476 con 11:10:37 /usr/bin/sleep
    pax 4268 2476 con 11:10:37 /usr/bin/sleep
    Mon Feb  9 11:10:41 WADT 2009
    Mon Feb  9 11:10:41 WADT 2009
    

    and a sleep 60:

    Mon Feb  9 11:11:51 WADT 2009
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    pax 4176 2600 con 11:11:51 /usr/bin/sleep
    Mon Feb  9 11:12:03 WADT 2009
    Mon Feb  9 11:12:03 WADT 2009
    ./limit10: line 20:  4176 Killed sleep 60
    

提交回复
热议问题