Bash – Why can’t I get pgrep output right to variable on bash script

bashexit-statuspgrepstderrstdout

I'm trying to make a script to either quit compton if it's running or start it if it's not running. I've read from man that it should exit 1 if process is found, so I've tried to make a script that uses that… However this just doesn't work, It starts if it's closed but doesn't close it. what am I doing wrong ??

#!/bin/bash


status=$(pgrep compton 2>&1)

if [[ $status == 1 ]];
    then
        killall compton
    else
        exec compton -b
fi

echo $status

Best Answer

You are getting the pgrep output in your status variable. It's just not the output that you expect it to be.

pgrep outputs the process IDs (PIDs) of the processes matching the pattern that you give it. If there is a process whose name matches compton, then $status would be the PID of that process, or of those processes. pgrep also returns an exit status, but an exit status is not captured by a command substitution as a string.

In your test, you compare $status against 1. It is unlikely that compton has PID 1.


If you want to kill any compton process if they exist, and start compton -b if no compton process exists, you may do that with

#!/bin/sh

if ! pkill compton; then
    exec compton -b
fi

This uses the exit status of pkill. The pkill tool works in an equivalent way to pgrep (they are usually distributed and installed as a pair) but instead of outputting PIDs of matching processes like pgrep would do, pkill sends the TERM signal (by default) to the matching processes.

The if keyword uses the exit status of the command that you use with it.

The ! inverts the sense of the test so that

  • If pkill compton succeeds, it means that there was one or several compton processes that have now been killed, or at least signalled, and exec compton -b will not be executed.

  • If pkill compton fails (no process matched the name, or there was some internal error in pkill), the body of the if statement would call your exec compton -b, which would replace the shell process with the process resulting from running compton -b.

Related Question