「pgrep」が引数を含むことを確認する式を処理するのを防ぐ方法は?

「pgrep」が引数を含むことを確認する式を処理するのを防ぐ方法は?

次のスクリプトがあります。実行していない場合は、プロセスを開始する必要があります。

$ 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

スクリプトは、取得するプロセス名が単一の単語(たとえば)の場合は正しく機能しますkeepalive_stackexchange_sample.bash sox_authfiles_auditd_v2r

ただし、検証中のプロセスにパラメータがある場合、pgrepそのパラメータはそのプロセスに固有のものと見なされ、スクリプトは期待どおりに機能しません。たとえば、次のように実行すると:

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

実行しましたが、keepalive_stackexchange_sample.bash sox_user_auditd_v2r -c次のエラーが発生します。

+ 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...'

sox_user_auditd_v2r -cスクリプトがすでに実行されていても実行されます。

パラメータ化されたプロセスでスクリプトを機能させる方法について提案がありますか?

答え1

pgrepがこれを単一の文字列として扱うように、プロセス名とオプションを引用する必要があります。

スクリプトを実行するときにこれを行うことができます。

keepalive_stackexchange_sample.bash 'sox_user_auditd_v2r -c'

またはスクリプト自体から:

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

これは、スクリプトのすべての引数が別々の単語ではなく1つの文字列であることを望むので、"$*"代わりに使用したい数少ない場合の1つです。 pgrepにはこれが必要です。"$@"pgrep一つパターン引数。

後でスクリプトでプロセスを再起動するときは、"$@"コマンドとそのオプションの両方が引数として必要になるため、シェルで別の単語として扱われる引数を使用する必要があります。

関連情報