如何在Python中执行进程并将数据写入stdin?

9 投票
3 回答
5310 浏览
提问于 2025-04-17 18:28

我在我的Python脚本里有一个标志,用来指示我是否设置并使用一个外部进程。这个进程是一个叫做 my_command 的命令,它从标准输入获取数据。如果我在命令行上运行它,命令大概是这样的:

$ my_command < data > result

我想用一个Python脚本生成一些 data 的行,通过修改标准输入,然后把它们传给 my_command

我正在做的事情大概是这样的:

import getopt, sys, os, stat, subprocess

# for argument's sake, let's say this is set to True for now
# in real life, I use getopt.getopt() to decide whether this is True or False
useProcess = True

if useProcess:
    process = subprocess.Popen(['my_command'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

for line in sys.stdin:
    # parse line from standard input and modify it
    # we store the result in a variable called modified_line
    modified_line = line + "foo"

    # if we want to feed modified_line to my_command, do the following:
    if useProcess:
        process.stdin.write(modified_line)

    # otherwise, we just print the modified line
    else:
        print modified_line

但是,my_command 好像没有收到任何数据,结果就出错退出了。我哪里做错了呢?

编辑

假设我的Python脚本叫做 my_Python_script。通常我会通过标准输入把一个叫 data 的文件传给 my_command

$ my_command < data > result

但现在我把它传给 my_Python_script 了:

$ my_Python_script < data > some_other_result

我希望 my_Python_script 能根据条件设置一个子进程,运行 my_command,处理 data 的内容(这些内容在传给 my_command 之前会被 my_Python_script 修改)。这样说更清楚了吗?

如果我用 bash 作为脚本语言,我会根据条件决定运行两个函数中的一个。一个会把数据行传给 my_command,另一个则不会。用Python也能做到这一点吗?

3 个回答

0

看起来你可能把参数和标准输入搞混了。你的命令应该是

$ <data> | mycommand result

在调用这个命令的时候,数据会被传入。

获取输入是通过 raw_input 这个内置函数来完成的。(http://docs.python.org/2/library/functions.html)

3

除了 @HaiVu 提到的 process.stdin.close(),你有没有使用 process.wait() 来等命令执行完再获取结果呢?

10

在向标准输入写入数据后,你需要关闭它:

    process.stdin.write(modified_line)
    process.stdin.close()

更新

我没有注意到 process.stdin.write() 是在一个循环里执行的。在这种情况下,你应该把 process.stdin.close() 移到循环外面。

另外,Raymond 提到我们还应该调用 process.wait()。所以更新后的代码应该是:

for ...
    process.stdin.write(modified_line)

process.stdin.close()
process.wait()

撰写回答