I sometimes find myself in the situation where I have a command running in my terminal, and want to run another command only after the first has finished. I’m pretty forgetful, so I don’t want to come back later and start the new command.
In the world of process forking, if you fork a child process you can then wait on that PID to finish in the parent. However, what if the process isn’t a child? What if they’re totally unrelated?
You can use a simple bash loop to monitor a PID, and then execute another command when it’s finished with this line:
while ps -p [pid] > /dev/null; do sleep 1; done; [cmd]
[pid] with the PID of the running process and
[cmd] with the command that you’re going to execute after it’s finished.
Alternatively, if this is something you do regularly, you might like to use this bash script I created:
#!/bin/bash pid=$1 me="$(basename $0)($$):" if [ -z "$pid" ] then echo "$me a PID is required as an argument" >&2 exit 2 fi name=$(ps -p $pid -o comm=) if [ $? -eq 0 ] then echo "$me waiting for PID $pid to finish ($name)" while ps -p $pid > /dev/null; do sleep 1; done; else echo "$me failed to find process with PID $pid" >&2 exit 1 fi
The script takes the existing process ID as an argument, checks to see whether it exists, then runs the loop to check that it’s running. It only exits when it’s finished. I put this in
/usr/local/bin/waiton and made it executable (
chmod +x). I could then do:
$ waiton 2000 && run command
This works really well with another script I created to find a PID by name, like this:
$ waiton $(findpid ruby) && run command