![当检查的进程包含“-c”(“pgrep”考虑参数)时,如何从脚本中使用“pgrep”?](https://linux22.com/image/217025/%E5%BD%93%E6%A3%80%E6%9F%A5%E7%9A%84%E8%BF%9B%E7%A8%8B%E5%8C%85%E5%90%AB%E2%80%9C-c%E2%80%9D%EF%BC%88%E2%80%9Cpgrep%E2%80%9D%E8%80%83%E8%99%91%E5%8F%82%E6%95%B0%EF%BC%89%E6%97%B6%EF%BC%8C%E5%A6%82%E4%BD%95%E4%BB%8E%E8%84%9A%E6%9C%AC%E4%B8%AD%E4%BD%BF%E7%94%A8%E2%80%9Cpgrep%E2%80%9D%EF%BC%9F%20.png)
以下脚本演示了我的问题,即确定进程是否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
将 视为 的参数-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