Ubuntu – How to wake a sleeping bash script

bashcommand line

Is it possible to wake a process that is paused using the sleep command?


As an example, lets say you have this script:

#!/bin/bash
echo "I am tired"
sleep 8h
echo "I am fresh :)"

After 30 minutes you discover that you need the script to stop, that is, you wished you had written sleep 30m instead.

You do not want to either call kill PID or press Ctrl+C, since then the last command is not executed and you will remain tired.

Is there a way to wake the process from sleep or perhaps use another command that supports wakeup? Solutions to both background and foreground processes are welcome.

Best Answer

When a Bash script is running a sleep, here's what the pstree might look like:

bash(10102)───sleep(8506)

Both have process IDs (PIDs), even when running as a script. If we wanted to interrupt the sleep, we'd send kill 8506 and the Bash session would resume... The problem is in a scripted environment we don't know the PID of the sleep command and there isn't a human to look at the process tree.

We can get the PID of the Bash session through the $$ magic variable. If we can store that somewhere, we can then target instances of sleep that are running underneath that PID. Here's what I'd put in the script:

# write the current session's PID to file
echo $$ >> myscript.pid

# go to sleep for a long time
sleep 1000

And then we can tell pkill to nuke sleep instances running underneath that PID:

pkill -P $(<myscript.pid) sleep

Again, this is limiting itself to only sleep processes running directly under that one Bash session. As long as the PID was logged correctly, this makes it a lot safer than killall sleep or pkill sleep, which could nuke any sleep process on the system (permissions allowing).

We can prove that theory with the following example where we have three separate bash sessions, two running sleep. Only because we're specifying the PID of the top-left bash session, only its sleep is killed.

enter image description here


An alternative approach is to push sleep into the background, store its PID and then return it to the foreground. In the script:

sleep 1000 &
echo $! > myscript.sleep.pid
fg

And to kill it:

kill $(<myscript.sleep.pid)
Related Question