確認されたプロセスに「-c」が含まれている場合、スクリプトで「pgrep」を使用する方法(「pgrep」は引数を考慮します)[コピー]

確認されたプロセスに「-c」が含まれている場合、スクリプトで「pgrep」を使用する方法(「pgrep」は引数を考慮します)[コピー]

sox_user_auditd_v2r -c次のスクリプトは、プロセスが実行されていることを確認する私の問題を示しています。

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

quoted="\'$@\'"

#if pgrep -x -f $@ > /dev/null; then
#if pgrep -x -f $quoted > /dev/null; then
#if pgrep -f $quoted > /dev/null; then
#if pgrep -f -- $quoted > /dev/null; then
#if pgrep -x $quoted > /dev/null; then
if pgrep -x -- $quoted > /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

./pgrep_stackexchange_sample.bash sox_user_auditd_v2r -cつまり、次のように実行するとpgrep誤動作してエラーが発生します。

+ pgrep -x -- '\'\''sox_user_auditd_v2r' '-c\'\'''
Usage: pgrep [-flvx] [-d DELIM] [-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]
        [-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] [PATTERN]

つまり、検査する正規表現の一部でなければならないpgrepパラメータとして扱われます。-cpgrep

-

フルラン出力:

$ ./pgrep_stackexchange_sample.bash sox_user_auditd_v2r -c
#!/bin/bash -xv

quoted="\'$@\'"
+ quoted='\'\''sox_user_auditd_v2r -c\'\'''

#if pgrep -x -f $@ > /dev/null; then
#if pgrep -x -f $quoted > /dev/null; then
#if pgrep -f $quoted > /dev/null; then
#if pgrep -f -- $quoted > /dev/null; then
#if pgrep -x $quoted > /dev/null; then
if pgrep -x -- $quoted > /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
+ pgrep -x -- '\'\''sox_user_auditd_v2r' '-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...'
Process 'sox_user_auditd_v2r -c' is not running. Starting it...
+ sox_user_auditd_v2r -c
+ echo 'Process '\''sox_user_auditd_v2r' '-c'\'' started successfully'
Process 'sox_user_auditd_v2r -c' started successfully
+ exit 0

誰が何が正確$quotedpgrep期待通りに機能するかを提案できますか?

編集1:

@ilkkachuの答えを実装しようとするとうまくpgrepいかないようです。それでも-c議論と見なされますpgrep

$ ./pgrep_stackexchange_sample.bash sox_user_auditd_v2r -c
#!/bin/bash -xv

quoted="$*"
+ quoted='sox_user_auditd_v2r -c'

#if pgrep -x -f $@ > /dev/null; then
#if pgrep -x -f $quoted > /dev/null; then
#if pgrep -f $quoted > /dev/null; then
#if pgrep -f -- $quoted > /dev/null; then
#if pgrep -x $quoted > /dev/null; then
if pgrep -x -f $quoted > /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
+ 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...'
Process 'sox_user_auditd_v2r -c' is not running. Starting it...
+ sox_user_auditd_v2r -c
+ echo 'Process '\''sox_user_auditd_v2r' '-c'\'' started successfully'
Process 'sox_user_auditd_v2r -c' started successfully
+ exit 0

答え1

quoted="\'$@\'"

これは、位置パラメータ(スクリプトのパラメータ)を連結し、スペースで連結し、開始と終了にこれらのバックスラッシュと一重引用符を追加します。だからあなたは例えば\'sox_user_auditd_v2r -c\'

pgrep -x -- $quoted

これにより、文字列が空白に分割され、引数で終わる複数のフィールドが形成されるため、次のように sumpgrep引数が得られます。\'sox_user_auditd_v2r-c\'

pgrep -x -- "\'sox_user_auditd_v2r" "-c\'"

これが行われる操作はによって異なりますpgrep---c\' いいえ選択肢として考えることもできますが、パターンとして見ることもできます。しかし、すべてのバージョンがマルチモードを許可するわけではないようです。pgrepおそらくそれはあなたが文句を言うかもしれません。 (逆スラッシュと一重引用符は引数文字列では一般的ではない可能性があるため、望むものではないかもしれません。)


代わりに、データから引用符を削除し、変数拡張の周りに配置します。また、"$*"パラメータを結合するにはforを使用する必要がありますが、whileは"$@"主に位置パラメータを個別に拡張するために使用されます。単にスカラー割り当てでは、複数のフィールド/パラメータに拡張することは機能しないため、同様のことを行いますが、より"$*"明確な意図があります。

pgrep -fプロセス名だけでなく、引数の完全なリストも一致させたいと思います。だからこんな感じ:

#!/bin/bash
key="$*"
pgrep -x -f "$key"

望むより:

答え2

@ilkkachuの優れた回答(およびGCを使用したデバッグセッション)に基づいて、次のスクリプトは期待pgrepどおりに機能します。

#!/bin/bash

# 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 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

関連情報