Bash – How to determine if a program is running when I start a shell and start that program if it is not already running

bashfedoraprocessshellzsh

When I start a shell, in my case bash and/or zsh, what lines do I need to add to .zshrc and/or .bashrc to check to see if a program is already running, and if the program is not already running, start it?

Example: I am starting a new zsh shell. If top is not already running, I would like to start top and have it take over the shell. If top is already running in another window, I would like the .zshrc to continue loading and give me an open terminal.

6-16 Update:

if ! pgrep -U $USER top >/dev/null; then
exec top
fi

The script above satisfies my request. The -q flag wouldn't work for me because -q is not an option on my system. So I had to pipe the PID to /dev/null. Thank you mveroone, Kusalananda, and Thomas Dickey.

I have some feature creep that is outside of the scope of the original question. Suppose I am on a single user system where I can become root without needing to enter a password. How would I autorun top as root if I needed to?

6-18
Ok, the feature creep issue of passing a command as root is resolved. I'm using this to launch several

Thank you for all of the thoughtful replies.

Best Answer

Use pgrep like this:

if ! pgrep -u $USER top >/dev/null 2>&1; then
    exec top
fi

Explanation:

  • The pgrep utility exits with a zero exit code if the command can be found running. Therefore, negate the test.
  • Also restrict it to the current user with -u $USER, so that it doesn't for some reason pick up someone else's processes. $USER is a standard shell variable. If that for some reason isn't defined, try using $LOGNAME instead, and if that fails, use $( id -n -u ) (but at that point you have to ask yourself what's going on, because $LOGNAME is also a standard shell variable).
  • We don't need the output from pgrep, so redirect the standard output and error streams to /dev/null.

If top (or whatever) isn't found to be running, exec it to replace the shell, as per the OP's question.

This should be working in all sh-compatible shells.

EDIT: The pgrep implementation on BSD systems (OS X, OpenBSD, ...) has a -q option that makes it discard any output, but the pgrep on Linux apparently doesn't have this flag. On BSD systems, use this rather than the slightly ugly redirect to /dev/null.

Related Question