当检查的进程包含“-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 -cpgrep会行为不当并抛出错误:

+ 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将 视为 的参数-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 -- $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

谁能建议什么是正确的$quoted,可以pgrep按预期工作?

编辑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

这会在空格上分割字符串,形成多个字段,最终作为 的参数pgrep,因此您会得到参数\'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

相关内容