【发布时间】:2016-02-21 22:35:13
【问题描述】:
我正在尝试unittest 一个从标准输入获取单个按键的模块。获取密钥的代码完美运行,但是将一个字符(字节?)准确地写入子进程的标准输入给我带来了一些问题。
我基本上使用的是推荐的 here,并根据文档和其他 SO 答案进行了修改:
for ch in range(0, 128):
p = sp.Popen(
[py, "-u", TEST_HELP, "getch"],
stdin=sp.PIPE,
stdout=sp.PIPE,
stderr=sp.PIPE,
bufsize=1
)
out, err = p.communicate(input=bytes(chr(ch), "ascii"))
print(out, ",", err)
我想要p 准确接收标准输入的一个ASCII 字符然后退出。事实上ch 有时是NUL、EOF 和其他控制字符不是问题;这正是我想要的。
问题是,在我按下 CTRL - C 之前,它似乎什么也不做,然后它以键盘中断退出。堆栈跟踪的最后一行是in selectors.py: fd_event_list = self._poll.poll(timeout),它告诉我它正在等待超时(?),但我没有提供timeout=int kwarg。
我正在使用的命令解析为python3 -u helptest.py getch,它看起来像这样,当我自己从命令行运行它时它可以正常工作。
这是helptest的相关部分:
def getch():
write_and_flush(ord(_ic._Getch()))
(write_and_flush 只是运行stdout.write; stdout.flush)
而_ic._Getch() 是:
def _Getch():
if sys.stdin.isatty():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
else:
return sys.stdin.read(1)
我在 subprocess 调用中做错了什么?
将调用更改为:
p = sp.Popen(
[py, TEST_HELP, "getch"],
stdin=sp.PIPE,
stdout=sp.PIPE,
stderr=sp.PIPE,
)
out, err = p.communicate(input=bytes(chr(ch) + "\n", "ascii"))
通过省略 bufsize、删除 --unbuffered 选项并添加“EOL”(以及其中的变体)不会/不会改变任何内容。
【问题讨论】:
标签: python subprocess