1

I have the following script; it is supposed to start a process if it is not running:

$ cat keepalive_stackexchange_sample.bash
#!/bin/bash -xv

This script checks if a process is running and starts it if it's not.

If the process is already running, the script exits with exit code 0.

If the process was restarted by the script, the script exits with exit code 0.

If the process fails to start, the script exits with exit code 2.

If the first argument is "-h" or "--help", the script prints a help message and exits with exit code 10.

if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then echo "Usage: $0 process_name" echo "This script checks if a process is running and starts it if it's not." exit 10 fi

if [[ -z "$1" ]]; then echo "Error: No process name provided." echo "Usage: $0 process_name" exit 12 fi

if pgrep -x -f $@ > /dev/null; then echo "Process '$@' is already running." exit 0 else echo "Process '$@' is not running. Starting it..." if ! "$@" &> /dev/null; then echo "Error: Failed to start process '$@'" exit 2 fi echo "Process '$@' started successfully" exit 0 fi

This script works fine if it the process name it gets has only one word, for instance keepalive_stackexchange_sample.bash sox_authfiles_auditd_v2r.

However, if the process I'm checking has arguments, pgrep thinks these arguments are meant for it, and the script does not work as expected, for instance, if I have running:

$ ps -ef | grep [s]ox_ | grep v2r
username   12150     1  0 23:07 ?        00:00:00 sox_user_auditd_v2r -c
$

and I run keepalive_stackexchange_sample.bash sox_user_auditd_v2r -c, I'll get the following error:

+ pgrep -x -f sox_user_auditd_v2r -c
pgrep: invalid option -- 'c'
Usage: pgrep [-flvx] [-d DELIM] [-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]
        [-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] [PATTERN]
+ echo 'Process '\''sox_user_auditd_v2r' '-c'\'' is not running. Starting it...'

and the script will run sox_user_auditd_v2r -c even though it is already running.

Any suggestion how can I have the script work on processes with arguments?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • 2
    You can try -- to signify the end of options - see for example What does "--" (double-dash) mean? however I suspect you will then get an error about passing more than one pattern to pgrep - you'll likely need to pass a single quoted string and use pgrep -x -f -- "$1", or perhaps change $@ to "$*" – steeldriver Feb 14 '23 at 23:42
  • Thanks, @steeldriver, but I cannot seem to find the right way to make pgrep to do what I want. See https://unix.stackexchange.com/questions/735653/how-to-use-pgrep-from-a-script-when-the-checked-process-includes-a-c-that – boardrider Feb 15 '23 at 18:34

1 Answers1

0

You need to quote the process name & options so that pgrep sees it as a single string.

You can either do that when running the script:

keepalive_stackexchange_sample.bash 'sox_user_auditd_v2r -c'

or in the script itself:

if pgrep -x -f "$*" > /dev/null; then ...

This is one of the few times when you want to use "$*" rather than "$@" because you want all of your script's args to become one string for pgrep rather than separate words - pgrep takes exactly one pattern argument.

Later in the script, when you re-start the process, you should use "$@" because you need to have the command and all its options as arguments treated as separate words by the shell.

cas
  • 78,579