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