ssh зависает, когда команда вызывается напрямую, но завершается чисто при запуске в интерактивном режиме - PullRequest
2 голосов
/ 29 августа 2008

Мне нужно запустить сервер на удаленном компьютере и получить номер порта, на котором находится процесс сервера. При вызове сервер прослушивает случайный порт и выводит номер порта на stderr.

Я хочу автоматизировать процесс входа на удаленный компьютер, запуска процесса и получения номера порта. Я написал Python-скрипт с именем "invokejob.py", который живет на удаленной машине, чтобы действовать как оболочка, которая вызывает задание, а затем возвращает номер порта, выглядит так:

import re, subprocess
executable = ... # Name of executable
regex = ... # Regex to extract the port number from the output
p = subprocess.Popen(executable,
    bufsize=1, # line buffered
    stderr=subprocess.PIPE
    )
s = p.stderr.readline()
port = re.match(regex).groups()[0]
print port

Если я вхожу в интерактивном режиме, этот сценарий работает:

$ ssh remotehost.example.com
Last login: Thu Aug 28 17:31:18 2008 from localhost
$ ./invokejob.py
63409
$ exit
logout
Connection to remotehost.example.com closed.

(Примечание: успешный выход из системы, он не завис).

Однако, если я пытаюсь вызвать его из командной строки, он просто зависает:

$ ssh remotehost.example.com invokejob.py

Кто-нибудь знает, почему он зависает во втором случае, и что я могу сделать, чтобы избежать этого?

Обратите внимание, что мне нужно получить выходные данные программы, поэтому я не могу просто использовать флаг ssh "-f" или перенаправить стандартный вывод.

Ответы [ 3 ]

3 голосов
/ 29 августа 2008
s = p.stderr.readline()

Я подозреваю, что это вышеупомянутая строка. Когда вы вызываете команду напрямую через ssh, вы не получаете полный pty (при условии Linux) и, следовательно, не можете читать из stderr.

Когда вы входите в систему в интерактивном режиме, для вас настраиваются stdin, stdout и stderr, и ваш скрипт работает.

0 голосов
/ 29 августа 2008

@ Бен Коллинз

Я думаю, вы правы, что проблема с stderr. Я уверен, что он блокирует вызов readline ().

В итоге я сдался и решил использовать модуль pxssh из pexpect для автоматизации моего взаимодействия с ssh-сессией.

@ Миша М

К сожалению, уловка с запятой здесь не работает: она блокирует выполнение моей программы.

0 голосов
/ 29 августа 2008

что делать, если вы делаете следующее:

ssh <remote host> '<your command> ;<your regexp using awk or something>'

Например

ssh <remote host> '<your program>; ps aux | awk \'/root/ {print $2}\''

Это позволит подключиться, выполнить и затем распечатать каждый PSID для любого пользователя root или любого процесса с root в его описании.

Я использовал этот метод для запуска всех видов команд на удаленных машинах. Уловка заключается в том, чтобы обернуть команды, которые вы хотите выполнить, в одинарные кавычки (') и отделить каждую команду точкой с запятой (;).

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