쉘 스크립트의 pargs에서 프로세스 명령줄 인수를 구문 분석합니다.

쉘 스크립트의 pargs에서 프로세스 명령줄 인수를 구문 분석합니다.

Bash 스크립트(Java 프로세스)에서 PID 목록을 얻고 해당 명령줄 인수를 구문 분석하여 각 PID가 해당하는 서버 인스턴스를 확인해야 합니다.

현재 저는 sed/cut을 사용하여 이 작업을 수행합니다.

  PARGS=$(pargs -l $PID)
  PARGS_ARR=($PARGS)
  NODE='UNKNOWN'
  for ARG in ${PARGS_ARR[@]}
  do
    # trim single quotes 
    ARG=$(echo $ARG | sed "s/'//g")

    # split by equals sign
    ARGL=$(echo $ARG | cut -f1 -d=)
    ARGR=$(echo $ARG | cut -f2 -d=)

    if [ "$ARGL" == "-DnodeId" ]; then
      NODE=$ARGR
    fi
  done

그러나 많은 수의 명령줄 매개변수(PID당 약 20-30개)로 인해 매우 느리게 실행됩니다.

어떻게든 명령줄 인수를 구문 분석하고 단일 명령을 사용하여 구문 분석된 키=>값을 얻는 방법이 있습니까?

답변1

출력은 어떻게 pargs -l $PID보입니까? 코드에서는 다음과 같은 형식의 모든 명령줄 인수를 포함하는 한 줄로 보입니다.

arg1=val1 arg2=val2

-DnodeId그렇다면 다음 명령을 사용하여 매개변수 값을 수집할 수 있습니다 sed.

$ ARGS="-DfirstArg=foo -DanotherArg=bar -DnodeId=1234 -DlastArg=baz"
$ echo "$ARGS" | sed -r 's/.*-DnodeId=([^ ]+).*/\1/g'
1234

따라서 스크립트는 다음과 같을 수 있습니다.

PARGS=$(pargs -l $PID)
NODE='UNKNOWN'
if [ -n "$(grep "DnodeId" <(echo "$PARGS"))" ]; then
    NODE=$(echo "$PARGS" | sed -r 's/.*-DnodeId=([^ ]+).*/\1/g')
fi

답변2

오른쪽에 있는 것이 무엇인지 관심이 있다면( =왼쪽에 있는 것이 있다면) -DnodeId다음과 같이 할 수 있습니다.

NODE=$(pargs -l $PID| awk -F '-DnodeId=' '{sub(" .*","",$2);print $2}')

-DnodeId=그러면 첫 번째 공백을 제외하고 패턴 오른쪽의 모든 항목이 인쇄됩니다 . 명령줄에 둘 이상이 있으면 -DnodeId첫 번째 항목에만 적용됩니다.

한 줄에 여러 개를 처리하는 -DnodeId것도 가능합니다 .

NODES=($(pargs -l $PID| awk -F '-DnodeId=' '{
          for(i=2;i<=NF;i++){
              sub(" .*","",$i);
              print $i
          }
        }'
))

답변3

당신이 하고 있는 일이 확실히 느려질 것 같습니다.var=$(command substitute)다음 단계로 진행하기 전에 중지하고 출력을 기다려야 합니다. 스트림에서 처리하면 대기 시간이 줄어들 것이라고 장담합니다.sed,이것stream editor:

NODE="$(pargs -l $PID | sed -rn '/(-DnodeId)=(\S*)/{s//\2/pq}')"

작은 따옴표가 무엇인지 잘 모르겠습니다. 방금 휴대폰에 입력했습니다. 하지만sed's y여전히 필요한 경우 함수가 확실히 처리할 수 있습니다.

위의 Josh는 실패 사례를 보여줍니다. 다음을 추가하는 것이 훨씬 간단할 수 있습니다.

${NODE:?PID not found...quitting}

위 실행 후sed주문하다.

제가 보기에는 이것들이 반드시 줄로 구분되어 있지는 않은 것 같습니다. 한 줄만 더 추가하면 쉽게 처리할 수 있습니다.|pipe- 여전히 하나의 데이터 스트림에 모두 포함되어 있으면서도 여러 일치 가능성도 고려합니다.

. <<PIDSED /dev/stdin
    $(pargs -l $PID |\
        sed -rn 's/(-DnodeId)=(\S*)/\
            echo "NODE$((i=i+1))=\2" ;/gp' |\
        . /dev/stdin)
PIDSED

답변4

bash매개변수 처리를 위해 외부 프로세스 대신 사용

for ARG in "${PARGS_ARR[@]}"
do
  # trim single quotes 
  ARG=${ARG//\'}

  # split by equals sign
  IFS="=" read ARGL ARGR <<< "$ARG"

  if [[ "$ARGL" == "-DnodeId" ]]; then
    NODE=$ARGR
  fi
done

관련 정보