我有以下脚本;如果它没有运行,它应该启动一个进程:
$ 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 将其视为单独的单词。