在写入stdin之前读取os.popen4的输出



我有一个脚本,它使用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')

也许你可以从这个角度倒过来做一些对你有用的东西。确保冲洗在适当的地方。

最新更新