6

Почему это не работает?

$ ssh vm "bullshitcommand; echo $?"
bash: bullshitcommand: command not found
0

Я ожидал ненулевой код возврата.

3 ответа3

7

Причина:

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 $?'

3

Вместо того чтобы говорить:

ssh vm "bullshitcommand; echo $?"

сказать:

ssh vm "bullshitcommand"
echo $?

Код возврата ssh будет таким же, как и у удаленной команды.

1

Вы сказали, это не работает

$ 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. Это дополнительная работа для сценария и программиста, которая делает это.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .