Могу ли я получить код завершения команды, выполняемой в подоболочке через ssh? - PullRequest
6 голосов
/ 17 марта 2011

Я пытаюсь использовать Paramiko для написания сценария развертывания, и у меня возникают проблемы с кодами выхода из команд, которые я запускаю.Я использую код, подобный этому в этом ответе , но он немного сложнее.По сути, из наших блоков разработки нам нужно пройти через сервер переходов, а оттуда - к серии производственных машин.Оказавшись там, мы должны переключиться на системного пользователя (sudo su - systemuser), а затем мы можем запускать команды.

Проблема в том, что, насколько я понимаю, у меня есть 3 подоболочки - сессия ssh, вложенная команда ssh и затем подоболочка su.Я не могу заставить Paramiko вернуть мне код завершения команд во внутренней подоболочке - я думаю, что код возврата, который он в конечном итоге вернет, будет кодом команды ssh.Я подозреваю, что эта проблема на самом деле не специфична для Paramiko - поддерживает ли протокол SSH такого рода использование?

В настоящее время я всегда выполняю:

(my command); echo "Process terminated with exit code $?"

и затем анализирую это наклиент, но это довольно уродливо - есть ли лучший способ?

Ответы [ 2 ]

8 голосов
/ 29 марта 2011

Полагаю, код возврата, который он в конечном итоге вернет, будет соответствовать команде ssh. Я подозреваю, что эта проблема на самом деле не специфична для Paramiko - поддерживает ли протокол SSH такого рода использование?

Да и нет.

Статус выхода всегда возвращается, но он может быть не там, где вы думаете. Когда вы вызываете invoke_shell(), ваш удаленный процесс становится оболочкой, вероятно, bash. exit_status, который вы получите, будет тем из этой оболочки, , а не любым из процессов, которые он выполнял. Paramiko (как и любая реализация ssh) может когда-либо возвращать состояние выхода ваших команд, потому что состояния выхода никогда не видны за пределами этой удаленной оболочки. Вам решать, каким должен быть ваш статус выхода, и выходить из оболочки с помощью exit $EXIT_STATUS (часто достаточно exit $?)

Если вы можете разбить ваши команды или обернуть их в сценарий, то используйте метод exec_command(), у вас будет прямой доступ к правильному состоянию выхода.

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

Все три из этих методов установят атрибут channel.exit_status как положено.

2 голосов
/ 18 марта 2011

У меня проблема с тем, что man-страница для 'ssh' говорит, что она возвращает код завершения процесса, который она запускает, но я не могу заставить его вернуть ненулевой код ошибки.Со страницы руководства ssh:

 The session terminates when the command or shell on the remote machine
 exits and all X11 and TCP/IP connections have been closed.  The exit sta‐
 tus of the remote program is returned as the exit status of ssh.

Это не похоже на правду.

Но я бы попробовал что-то подобное и посмотрел бы, что происходит в вашей системе.

% ssh localhost bash -c "exit 3" ; echo $?
0

Когда я запускаю подобную команду локально, bash возвращает код выхода.

% bash -c 'exit 3' ; echo $?
3

Двойные кавычки будут удалены до того, как ssh покажет команды.Итак, давайте попробуем больше цитат.

% ssh localhost bash -c "'exit 3'" ; echo $?
3

Бинго.«Выход 3» превращался в «выход», за которым следовало пропущенное слово в командной строке bash.Таким образом, bash запускал команду «exit».

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

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