如何防止“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 ...

这是您想要使用"$*"而不是"$@"因为您希望所有脚本的参数成为一个字符串pgrep而不是单独的单词的少数情况之一 - pgrep 恰好需要模式论证。

稍后在脚本中,当您重新启动进程时,您应该使用,"$@"因为您需要将命令及其所有选项作为参数,由 shell 将其视为单独的单词。

相关内容