抑制子进程的输出

Suppress output of subprocess

我想使用 subprocess 模块来控制一些通过 ssh 生成的进程。

通过搜索和测试,我发现这行得通:

import subprocess
import os
import time

node = 'guest@localhost'
my_cmd = ['sleep','1000']
devnull = open(os.devnull, 'wb')
cmd = ['ssh', '-t', '-t', node] + my_cmd
p = subprocess.Popen(cmd, stderr=devnull, stdout=devnull)


while True:
    time.sleep(1)
    print 'Normal output'

我提供的 -t -t 选项允许我终止远程进程,而不仅仅是 ssh 命令。但这也扰乱了我的程序输出,因为换行符不再有效,使其成为一个长而难以阅读的字符串。

如何使 ssh 不影响 python 程序的格式?

示例输出:

guest:~$ python2 test.py 
Normal output
             Normal output
                          Normal output
                                       Normal output
                                                    Normal output
                                                                 Normal output
                                                                              Normal output
(First ctrl-c)
Normal output
Normal output
Normal output
(Second ctrl-c)
^CTraceback (most recent call last):
  File "test.py", line 13, in <module>
    time.sleep(1)
KeyboardInterrupt

好的,现在输出很清楚了。我不完全知道为什么,但是命令 ssh -t -t 将本地终端置于原始模式。无论如何,这是有道理的,因为它的目的是让您可以直接在远程使用curses程序(例如vi),并且在这种情况下,不应进行任何转换,即使是简单的 \n -> \r\n 允许一个简单的新行将光标留在第一列。但是我在 ssh 文档中找不到这方面的参考。

它 (-t -t) 允许你杀死远程进程,因为原始模式让 Ctrl + C 被发送到远程而不是被处理本地 tty 驱动程序。

恕我直言,这是 design smell,因为你只使用 pty 分配的副作用来传递 Ctrl + C遥控器和您遭受另一个副作用,即本地系统上的原始模式。您应该处理标准输入 (stdinput = subprocess.PIPE) 并在您在本地键盘上输入特殊字符时显式发送 chr(3),或者为执行此操作的 SIG-INT 安装信号处理程序。

或者,作为一种解决方法,您可以在启动远程命令后简单地使用类似 os.system("stty opost -igncr") 的东西(或更好的子进程等效项)以将本地终端重置为可接受的模式。