Pavan
Pavan

Reputation: 1

Timeout in shellscript

I want to put timeout in my shell script for process to be done within that,for example if I want to scp one file, if that file doesn't transfered within timeout through an error, if success echo a success message, how to put timeout ?

Upvotes: 0

Views: 890

Answers (2)

Noufal Ibrahim
Noufal Ibrahim

Reputation: 72745

Use timeout(1). Much better than a homebrew solution which you'll have to write, debug and maintain.

Upvotes: 1

ShellFish
ShellFish

Reputation: 4551

Use this for example:

command &    # start a new process in background
pid=$(pidof command | cut -f1 -d' ')    # save pid of started process
sleep(timeout_value)    # set timeout value to match your desired time to process
pids=$(pidof command)    # get all pids of running processes of this command
if [[ $(grep "$pid" "$pids") ]]; then    # if started process still running
    echo "error"
else
    echo "success"
fi

Change the word command to match your actual command. I'm not sure if this will work with a pipeline, I'll test it out in a minute and get back to you.

For a pipeline command you could do the following (provided you're executing using bash):

(command | other_command | ...) &
pid=$(pidof bash | cut -f1 -d' ')    # save pid of started process
sleep(timeout_value)    # set timeout value to match your desired time to process
pids=$(pidof bash)    # get all pids of running bash processes
if [[ $(grep "$pid" "$pids") ]]; then    # if started process still running 
    echo "error"
else
    echo "success"
fi

Problem

Note that there are better answers out there as this script will always wait out the entire timeout. Which might not be what you desire.

Possible solution

A possible solution is to sleep multiple times, something like this:

for i in $(seq 1..100); do
    sleep(timeout/100)  # sample the timeout interval
    pids=$(pidof bash)
    if [[ $(grep -v "$pid" "$pids") ]]; then   # if process no longer running
        echo "succes" && exit 0     # process completed, success!
    elif [[ $i -eq 100 ]]; then
        echo "error"    # at the end of our timeout
    fi
done

Note: change the value 100 if your timeout is really long, try to optimize it so timeout per iteration is not too long.

Upvotes: 0

Related Questions