Почему это не работает?
$ ssh vm "bullshitcommand; echo $?"
bash: bullshitcommand: command not found
0
Я ожидал ненулевой код возврата.
Причина:
echo $?
вы на самом деле отправляете локальную переменную $?
и, кажется, просят отобразить его в оболочке ssh.
Вы можете доказать это, используя несуществующую команду перед оператором ssh.
Например:
notexistingcommand; ssh vm "echo $?"
выходы
bash: несуществующаякоманда: команда не найдена
127
или даже
export var=123; ssh vm "echo $var"
выводит
123
Решение:
То, что вы можете сделать, чтобы использовать удаленную переменную, экранируется, и это будет выплевывать -1 (или 127):
ssh vm "nonexistentcmd; echo \$?"
Или вы можете использовать одинарные кавычки ('), так как они не раскрывают переменные и буквально принимают символ $
ssh vm 'nonexistentcmd; echo $?'
Вместо того чтобы говорить:
ssh vm "bullshitcommand; echo $?"
сказать:
ssh vm "bullshitcommand"
echo $?
Код возврата ssh
будет таким же, как и у удаленной команды.
Вы сказали, это не работает
$ ssh vm "bullshitcommand; echo $?"
bash: bullshitcommand: command not found
0
Сначала давайте проанализируем персонажей:
"not important $? not important"
интерпретируется локально на стороне клиента, а не на сервере. Это будет интерпретироваться как:
"not important 0 not important"
потому что на стороне клиента (локальная) специальная переменная $? обычно 0. Для предотвращения этого вы должны сделать экранирование, потому что вы хотите поместить текст $? без замены:
"not important \$? not important"
Другая проблема заключается в том, что вы делаете. Вы просто потеряли интересующий вас код выхода. Давайте посмотрим на пример ниже:
$ ssh vm "bullshitcommand; echo external ret: \$?"; echo internal ret: $?
bash: bullshitcommand: command not found
external ret: 127
internal ret: 0
что случилось? внешний $? перехватывает код выхода, затем на один шаг после этого у вас есть код выхода из команды echo. Это всегда 0, потому что у echo нет возможности аварийно завершить работу :) И, наконец, ssh-сервер получает код выхода из последней команды, он получен из echo и равен 0. После этого 0-й код выдается клиентом ssh. Наконец, эта команда ssh завершает работу с 0.
Вы можете обойти это путем временной экономии $? значение, например, так:
$ ssh vm "bullshitcommand; exitcode=\$? echo external ret: \$exitcode; exit \$exitcode"; echo internal ret: $?
bash: bullshitcommand: command not found
external ret: 127
internal ret: 127
Когда вы получите этот результат, вы дома :). Проблема в том, что exitstatus - это несовершенство, и выше у вас есть обходной путь для этого. Помни о побеге :)
Но обратите внимание на исторические сломанные ssh-серверы и клиенты. Иногда сервер и / или клиент игнорируют состояние выхода и постоянно возвращают 0 код возврата. Проверьте это, если вы должны быть уверены. Если у вас есть такая ситуация, вы должны обновить программное обеспечение или сделать обходной путь с передачей кода выхода потоком stdout. Это дополнительная работа для сценария и программиста, которая делает это.