Watching Processes with ps

In this post I’ll look at how you would monitor a process on a system in a BASH script. In particular, we’ll consider the case where we want to determine if a file is done uploading via scp. If you have lsof or fuser installed on your system, this is not difficult, but you can’t always count on these tools being installed.

If you own the process, then you can use the ps utility with the U option and provide your username. That will filter all of the processes by username.

ps U <username>

But you probably don’t own this process, so you’ll need to get a little bit more creative. First, you’ll want to consider all of processes across all of the users, and then you’ll want to narrow that down by the processes that have files associated with them. This is accomplished by using the -ef tag; e for each or every, and f for file. Then you’ll want to pipe the output of ps through the grep utility and search for scp.

ps -ef | grep "scp" 

This is cool, but this will return all processes containing scp, and it will return the grep process you just called. If you want to exclude you grep search and narrow things down by a given directory, or a specific file, you’ll need to add more grep filters like so,

ps -ef | grep "scp" | grep <stuff> | grep -v "grep"

The -v option on the grep call inverts the selection. Now we can check for the process in our BASH script by taking advantage of the error code returned by the grep utility.

var=`ps -ef | grep "scp" | grep <stuff> | grep -v "grep"`
if [ $? -eq 1 ] ; then
    echo "We were not able to find the scp process associated with the <stuff> file or directory."
    echo "It must have completed."
fi

This bit of code checks the output of the last grep call, held in the $? variable. If $? is 0, then grep matched an scp process associated with the directory or file you were interested in. Otherwise, if it fails and $? is 1, then the scp process probably finished.

I don’t know that this is the best way to go about this, but it’s a pretty good way.