Более простой путь состоял бы в том, чтобы использовать a case
оператор вместо проверки $?
неоднократно:
case "$?" in
0) echo "Password successfully changed on $host by $user" ;;
1) echo "Failure, password unchanged" ;;
2) echo "Failure, new and old passwords are too similar" ;;
3) echo "Failure, password must be longer" ;;
*) echo "Password failed to change on $host" ;;
esac
Как выглядит вывод команды 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
Если все, что вас волнует, это то, что идет справа от =
, если то, что слева, - -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
}
}'
))
Кажется, что то, что вы делаете, определенно будет очень медленным, поскольку каждый раз, когда вы var = $ (command substitute)
, вы должны останавливаться и ждать его вывода, прежде чем переходить к следующему шагу. Готов поспорить, что вы бы подождали гораздо меньше, если бы просто обработали его в потоке с помощью sed,
редактора потока :
NODE="$(pargs -l $PID | sed -rn '/(-DnodeId)=(\S*)/{s//\2/pq}')"
Я не совсем уверен насчет одинарных кавычек - Я только что набрал это на своем телефоне, но функция sed y
определенно справится с этим, если она вам все еще нужна.
Выше Джош демонстрирует неудачный случай. Вероятно, было бы намного проще просто добавить:
${NODE:?PID not found...quitting}
После выполнения вышеуказанной команды sed
.
Мне приходит в голову, что они не обязательно уже разделены строкой, мы можем справиться с этим достаточно легко с помощью еще 1 | pipe
- все еще в одном потоке данных, а также с учетом возможности нескольких совпадений :
. <<PIDSED /dev/stdin
$(pargs -l $PID |\
sed -rn 's/(-DnodeId)=(\S*)/\
echo "NODE$((i=i+1))=\2" ;/gp' |\
. /dev/stdin)
PIDSED
Обрабатывайте аргументы с помощью 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