Терминал испортился (не отображаются новые строки) после запуска скрипта Python

У меня есть скрипт Python, который я использую для параллельного выполнения команд на нескольких хостах с помощью модуля подпроцесса Python. Это обертка SSH, и в основном делает вызов так:

output = subprocess.Popen(["/bin/env", env, "/usr/bin/ssh", "-t", "%s@%s" % (user, host), "--", command], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

Эффективная команда выполняется следующим образом:

/bin/env TERM=$TERM:password /usr/bin/ssh -t "%s@%s" % (user, host), "--", command

Это работает нормально, за исключением того, что я получаю неустойчивую ошибку, когда мой терминал портится (теряет переводы строки) после запуска скрипта. "Сброс" из командной строки исправляет это, но я точно не знаю, как это происходит. Я заметил, что иногда в конце первого элемента в выводе кортежа есть "\r\n", а иногда его там нет. Смотрите следующее, а именно: "Отказано в доступе \ r \ n":

**** Okay output ****
[user@/home/user]# ./command.py hosts.lists "grep root /etc/shadow"
Running command "grep root /etc/shadow" on hosts in file "hosts.test"
('grep: /etc/shadow: Permission denied\r\n', 'Connection to server1.example.com closed.\r\n')
('grep: /etc/shadow: Permission denied\r\n', 'Connection to server2.example.com closed.\r\n')
[user@/home/user]#


**** Output causes terminal to not display newlines ****
[user@/home/user]# ./command.py hosts.list "grep root /etc/shadow"
('grep: /etc/shadow: Permission denied\r\n', 'Connection to server1.example.com closed.\r\n')
('grep: /etc/shadow: Permission denied\n', 'Connection to server2.example.com closed.\r\n')
                                 [user@/home/user]# [user@/home/user]# [user@/home/user]

Второй вывод был немного изменен, но показывает отсутствующий "\r" и то, как мое приглашение "испортилось" после запуска скрипта.

Я думаю, что это связано с использованием опции "-t" в моей команде подпроцесса. Каким-то образом я теряю. Если я уберу опцию "-t", эта проблема исчезнет, ​​но в двух словах, она мне понадобится для прохождения через переменные окружения для использования на удаленном компьютере (я хакерски использую переменную TERM для прохождения пароля пользователя для Цель sudo, потому что я не могу предположить, что AcceptEnv разрешает передачу произвольной переменной на удаленный sshd-сервер; я делаю это, чтобы избежать передачи пароля в командной строке, которая будет отображаться в списке процессов на удаленном компьютере).

Просто интересно, если кто-нибудь знает способ обойти это, не удаляя опцию "-t"?

ОБНОВЛЕНИЕ: Похоже, что мои настройки tty изменяются после выполнения команды subprocess.Popen(...). Connect () в моем скрипте, независимо от того, действительно ли я выводил вывод на экран. Я нахожу это действительно странным. Вот различия до / после в моем tty config (из stty -a):

-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff


opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0

isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt

Мне интересно, как перестать общаться () от изменения настроек моего терминала? Это возможно, или это ошибка?

2 ответа

Я нашел это

stty sane

восстанавливает консоль так, как это было раньше. Я не совсем понял другой ответ здесь, так что это кому-то помогает.

Нашел ответ здесь.

У меня была такая же проблема в скрипте Perl. Для решения этой проблемы мне пришлось сохранить текущие настройки локального терминала (чтобы восстановить его в конце скрипта) и добавить "stty -raw" перед выполнением удаленной команды.

Итак, в Perl:

# Сохранить текущие настройки терминала (вы можете добавить PID в имени файла)

`stty -g> ~ / tmp /.currentTtySettings`;

# Выполнить удаленную команду, добавив "stty -raw"

my @ out = `ssh -t -q user@server1.example.com" stty -raw; grep root / etc / shadow "`;

# Восстановить настройки терминала

`stty \`cat ~/tmp/.currentTtySettings\``;

Надеюсь, это поможет вам!

Другие очень полезные ссылки:

Подробное объяснение ssh и tty (опция -t) https://unix.stackexchange.com/questions/151916/why-is-this-binary-file-being-changed

Некоторое вдохновение Perl и ssh http://search.cpan.org/~bnegrao/Net-SSH-Expect-1.09/lib/Net/SSH/Expect.pod

-Как избежать "-t" для sudo https://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password

Другие вопросы по тегам