Search code examples
bashgrepcommand-substitution

bash: pgrep in a commad substition


I want to build a small script (called check_process.sh) that checks if a certain process $PROC_NAME is running. If it does, it returns its PID or -1 otherwise.

My idea is to use pgrep -f <STRING> in a command substitution.

If I run this code directly in the command line:

export ARG1=foo_name
export RES=$(pgrep -f ${ARG1})
if [[ $RES == "" ]]; then echo "-1" ; else echo "$RES"; fi

everything goes fine: PID or -1 depending on the process status.

My script check_process.sh contains the same lines plus an extra variable to pass the process' name :

#!/bin/bash
export ARG1=$1
export RES=$(pgrep -f ${ARG1})
if [[ $RES == "" ]]; then echo "-1" ; else echo "$RES"; fi

But this code does not work! If the process is currently running I get two PIDs (the process' PID and something else...), whereas when I check a process that is not running I get the something else !

I am puzzled. Any idea? Thanks in advance!


Solution

  • If you add the -a flag to pgrep inside your script, you can see something like that (I ran ./check_process.sh vlc):

    17295 /usr/bin/vlc --started-from-file ~/test.mkv
    18252 /bin/bash ./check_process.sh vlc
    

    So the "something else" is the pid of the running script itself.

    The pgrep manual explains the -f flag:

    The pattern is normally only matched against the process name. When -f is set, the full command line is used.

    Obviously, the script command line contain the lookup process name ('vlc') as an argument, hence it appears at the pgrep -f result.

    If you're looking just for the process name matches you can remove the -f flag and get your desired result.

    If you wish to stay with the -f flag, you can filter out the current pid:

    #!/bin/bash
    ARG1=$1
    TMP=$(pgrep -f ${ARG1})
    RES=$(echo "${TMP}" | grep -v $$)
    if [[ $RES == "" ]]; then echo "-1" ; else echo "${RES}"; fi