확인된 프로세스에 "-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

누구든지 무엇이 정확 $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

이렇게 하면 문자열이 공백으로 분할되어 인수로 끝나는 여러 필드가 형성되므로 다음과 같이 sum 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

관련 정보