我有一个脚本,它使用os.popen4执行一些命令。问题是,执行命令时需要用户输入("y"或"n")。我正在读取stdout/stderr并打印它,但来自命令的问题似乎并没有打印出来,它挂起了。为了使它发挥作用,我不得不盲目地将"n"写入stdin。能请人指导一下如何处理它吗?
代码不起作用:
(f_p_stdin, f_p_stdout_stderr) = os.popen4(cmd_exec,"t")
cmd_out = f_p_stdout_stderr.readlines()
print cmd_out
f_p_stdin.write("n")
f_p_stdin.close()
f_p_stdout_stderr.close()
工作代码:
(f_p_stdin, f_p_stdout_stderr) = os.popen4(cmd_exec,"t")
cmd_out = f_p_stdout_stderr.readlines()
f_p_stdin.write("n")
f_p_stdin.close()
print cmd_out
f_p_stdout_stderr.close()
注意:我知道它已经折旧,并且使用了子流程模块,但现在我不知道如何使用它。所以如果有人能帮助我使用os.popen4处理它,我将不胜感激。我想捕捉这个问题,处理用户的输入并执行它。
readlines()
:返回一个包含文件中所有数据行的列表。如果像本例中那样从进程中读取,它很有可能不会发送换行符和/或刷新输出。你应该从输入中读取字符并进行处理,看看问题是否被提出。
了解cmd_exec
是什么样子会有所帮助,这样其他人就可以尝试并模仿你的尝试。
更新:
我用Python编写了一个uncheckout
命令:
#! /usr/bin/env python
# coding: utf-8
import sys
print 'Uncheckout of {} is irreversible'.format(sys.argv[1])
print 'Do you want to proceed? [y/N]',
sys.stdout.flush()
x = raw_input()
if x == 'y':
print sys.argv[1], "no longer checked out"
else:
print sys.argv[1], "still checked out"
我特意将提示字符串作为raw_input的参数,以便能够显式地执行flush()
。
您的两个代码片段都不适用于此(假设cmd_exec
是['./uncheckout', 'abc.txt']
或'./uncheckout abc.txt'
,popen4()
在后一种情况下使用shell来启动程序)。只有当我将readlines()
移动到write()和close()之后,命令才会继续。这对我来说很有意义,因为close()会刷新输出。您在文本模式下写作,它通常缓冲到行尾,而行尾不在.write('n')
中。
为了能够检查提示是什么,并对此进行测试和反应。,以下内容适用于上述uncheckout
:
#! /usr/bin/env python
# coding: utf-8
import os
import sys
cmd_exec = ['./uncheckout', 'abc.txt']
(f_p_stdin, f_p_stdout_stderr) = os.popen4(cmd_exec,"t")
line = ''
while True:
x = f_p_stdout_stderr.read(1)
if not x:
break
sys.stdout.write(x)
sys.stdout.flush()
if x == 'n':
line = ''
else:
line += x
if line.endswith('[y/N]'):
f_p_stdin.write("nn")
f_p_stdin.flush()
sys.stdout.write('n')
也许你可以从这个角度倒过来做一些对你有用的东西。确保冲洗在适当的地方。