Получение статуса выхода, хранящегося в переменной внутри команды ssh - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь проверить этот статус предыдущей команды в списке команд, отправленных на сервер для смены пароля.Когда я просто echo $? это работает.когда я сохраняю его в переменной типа STATUS=$?, а затем echo $STATUS, я получаю пустую строку.И когда я помещаю echo $? в свой цикл if, тогда тоже возвращается что-то странное.Ниже приведен код команды ssh для любых советов, как это исправить.

ssh root@192.168.56.13 "printf '%s\n%s' "$PASSWORD" "$PASSCONFIRM" | passwd; STATUS=$?; echo $STATUS; if (( $STATUS == 0 )); then printf 'Password Changed Successfully\n'; else printf 'Password Change Unsuccessful\n'; fi; sleep 1;"
Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully

Password Change Unsuccessful
bash: ((: == 0 : syntax error: operand expected (error token is "== 0 ")

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Во-первых, ссылки на переменные (например, $STATUS) расширяются локальной оболочкой еще до того, как команда будет отправлена ​​на удаленный компьютер, не говоря уже о выполнении.Чтобы предотвратить это, вам нужно экранировать $ (например, \$STATUS), чтобы он просто передавался в удаленную систему, а не интерпретировался локально.

Во-вторых, кавычки не вкладываются.Вы пытаетесь вложить двойные кавычки в строку в двойных кавычках, и это не работает;вам нужно избегать внутренних двойных кавычек (как и $).

Вы можете проверить это, используя echo вместо ssh.Обычно это плохой способ сказать, что происходит с командой оболочки, потому что echo показывает, как выглядят аргументы после , которые они прошли через процесс разбора оболочки.Но в этом случае это именно то, что будет отправлено в удаленную систему, так что это то, что вы хотите.Вот пример:

$ PASSWORD='p4ssw0rd'
$ PASSCONFIRM='p4ssw0rd'
$ echo "printf '%s\n%s' "$PASSWORD" "$PASSCONFIRM" | passwd; STATUS=$?; echo $STATUS; if (( $STATUS == 0 )); then printf 'Password Changed Successfully\n'; else printf 'Password Change Unsuccessful\n'; fi; sleep 1;"
printf '%s\n%s' p4ssw0rd p4ssw0rd | passwd; STATUS=0; echo ; if ((  == 0 )); then printf 'Password Changed Successfully\n'; else printf 'Password Change Unsuccessful\n'; fi; sleep 1;

Обратите внимание на «STATUS=0; echo ; if (( == 0 ))» - это потому, что все ссылки на переменные ($? и $STATUS) были расширены локально, до 0 и «» соответственно.Вот версия с добавленными соответствующими escape-кодами:

$ echo "printf '%s\n%s' \"$PASSWORD\" \"$PASSCONFIRM\" | passwd; STATUS=\$?; echo \$STATUS; if (( \$STATUS == 0 )); then printf 'Password Changed Successfully\n'; else printf 'Password Change Unsuccessful\n'; fi; sleep 1;"
printf '%s\n%s' "p4ssw0rd" "p4ssw0rd" | passwd; STATUS=$?; echo $STATUS; if (( $STATUS == 0 )); then printf 'Password Changed Successfully\n'; else printf 'Password Change Unsuccessful\n'; fi; sleep 1;

Кстати, обратите внимание, что я предполагаю, что PASSWORD и PASSCONFIRM являются локальными, а должен быть расширен локально, поэтому я не сделал$ на тех.Но есть потенциальная проблема: если какое-либо значение содержит что-либо, что интерпретируется внутри двойных кавычек, удаленная оболочка будет интерпретировать его.Так, например, если ваш пароль p4$$w0rd, $$ будет заменен идентификатором процесса удаленной оболочки.Было бы лучше использовать одинарные кавычки вокруг них, но если они содержат одинарные кавычки, возникнет хаос:

$ PASSWORD="p4'\$\$w0rd"
$ echo "$PASSWORD"    # show the true password
p4'$$w0rd
$
$ # This will not work right, because of the $$:
$ echo "printf '%s\n%s' \"$PASSWORD\" \"$PASSCONFIRM\" ..."
printf '%s\n%s' "p4'$$w0rd" "p4ssw0rd" ...
$
$ # Neither will this, because of the single-quote:
$ echo "printf '%s\n%s' '$PASSWORD' '$PASSCONFIRM' ..."
printf '%s\n%s' 'p4'$$w0rd' 'p4ssw0rd' ...
$
$ # But this, while messy, will work:
$ ESCAPEDPW=${PASSWORD//\'/\'\\\'\'}
$ ESCAPEDCONFIRM=${PASSCONFIRM//\'/\'\\\'\'}
$ echo "printf '%s\n%s' '$ESCAPEDPW' '$ESCAPEDCONFIRM' ..."
printf '%s\n%s' 'p4'\''$$w0rd' 'p4ssw0rd' ...

... подождите, я слышал, вы говорите, , что будет работать?Да, и вот демонстрация того, что этот бестолковый пароль будет делать в удаленной системе:

$ printf '%s\n%s' 'p4'\''$$w0rd' 'p4ssw0rd'
p4'$$w0rd
p4ssw0rd

(Обратите внимание, что они не совпадают, потому что я не удосужился обновить PASSCONFIRM.)

0 голосов
/ 11 декабря 2018

Вам нужно будет указать переменные, которые вы хотите использовать на удаленном сервере.

$PASSWORD и $PASSWORDCONFIRM в порядке, они используются на локальном сервере.

$STATUS и $?, которые вы хотите затем оценить на удаленном сервере, поэтому вам нужно будет их ограничить: STATUS=\$?, echo \$STATUS и if (( \$STATUS == 0))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...