«Псевдо-терминал не будет выделен, потому что stdin не является терминалом» при запуске ssh через python без paramiko - PullRequest
4 голосов
/ 12 января 2011

Я запускаю ssh из Python без использования внешней библиотеки, такой как Paramiko. У меня есть причины сделать это таким образом, а не через внешнюю библиотеку.

В основном я делаю subprocess.Popen("ssh -t bla -- command")

При этом я получаю следующее сообщение:

Pseudo-terminal will not be allocated because stdin is not a terminal.

Причина, по которой я запускаю его с -t, заключается в том, что я хочу, чтобы удаленная команда завершилась, когда я уничтожаю свой скрипт на python.

Когда я пытаюсь с помощью -t -t (заставить его), я получаю следующее сообщение:

tcgetattr: Inappropriate ioctl for device

Есть ли способ запустить команду ssh с -t через Python?

Ответы [ 3 ]

2 голосов
/ 12 января 2011

Могу ли я с уважением предположить, что вы задаете неправильный вопрос, и что правильный вопрос может быть что-то вроде «как мне убедиться, что подпроцесс завершается, когда моя программа python завершается»

Вы могли бы сделать некоторыеумные вещи в Unix, такие как выделение pty и убедитесь, что ваш подпроцесс использует это как std in out и т. д., так что команда ssh думает, что она обращается к терминалу, а не к каналу, но это, вероятно, не то, что вы действительно хотите сделать.

1 голос
/ 06 мая 2013

Чтобы завершить удаленную команду, когда сценарий python убит, вы можете (в качестве альтернативы опции -t для ssh) применить обходной путь, который использует именованный канал для преобразования "EOF в SIGHUP", когда stdin sshd закрывается (см. Ошибка 396 - sshd обрабатывает сирот, когда pty не выделено ).

# sample code in Bash

# press ctrl-d for EOF
ssh localhost '
TUBE=/tmp/myfifo.fifo
rm -f "$TUBE"
mkfifo "$TUBE"
#exec 3<>"$TUBE"

<"$TUBE" sleep 100 &  appPID=$!

# cf. "OpenSSH and non-blocking mode", 
# http://lists.mindrot.org/pipermail/openssh-unix-dev/2005-July/023090.html
#cat >"$TUBE"
#socat -u STDIN "PIPE:$TUBE"
dd of="$TUBE" bs=1 2>/dev/null
#while IFS="" read -r -n 1 char; do printf '%s' "$char"; done > "$TUBE"

#kill -HUP -$appPID 
kill $appPID

rm -f "$TUBE"
'
0 голосов
/ 12 апреля 2011

Звучит так, будто вы действительно просите обратную старую команду nohup ; то есть какой-то способ гарантировать, что удаленная команда реагирует на сигнал HUP (зависания), который генерируется драйвером TTY (PTY или psuedo-tty), когда основное соединение с ним закрыто.

Лично я подозреваю, что Paramiko будет гораздо лучше, чем пытаться управлять этим с помощью модуля subprocess . Вы можете сделать так, чтобы Paramiko открывал соединение, распределял pty и выполнял ваши команды без всяких усилий; и код для использования существующих known_hosts и идентификационных файлов (личных ключей) относительно прост.

Этот рецепт Копирование файлов через SSH с использованием paramiko в ActiveState показывает основы загрузки ssh known_hosts, использования файлов идентификации и взаимодействия с любым ssh агентом , который вы, возможно, используете. Оттуда то, что вы просите, должно быть просто вопросом:

Также можно использовать реализацию TwistedConch протоколов SSH. Тем не менее, обернуть голову вокруг Twisted Framework программирования может быть довольно сложным.

Вот пример простого ssh-сервера в Twisted с поддержкой pty: Twisted Conch за 60 секунд: запросы PTY Вот SO поток всего за неделю до публикации вашего Лучший способ запуска удаленных команд через ssh в Twisted? , но это вообще не затрагивало проблемы, связанные с pty. Изучение документов для twisted.conch.ssh.session показывает, что у него есть поддержка pty; но перечисляет это как «Недокументированное».

Конечно, вы могли бы даже пойти с Pexpect , запустить оболочку для локального ssh клиента и отправить через него удаленную команду. Это будет наиболее близко эмулировать способ запуска команды из вашей собственной оболочки.

...