Терминал испортился (не отображаются новые строки) после запуска скрипта 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