在python中使用管道;“子流程”;模块

在python中使用管道;“子流程”;模块,python,batch-file,subprocess,Python,Batch File,Subprocess,假设我想调用windows批处理文件中的程序。代码如下所示: exit | theprogram arg1 我已经测试过了,效果非常好,非常感谢 现在,策略发生了重大变化,我必须在python脚本中调用该程序。为此,我使用子流程模块。我得到: subprocess.call(['theprogram', arg1]) 但是为了让它正常工作,我需要使用exit语句来处理它,就像我在批处理文件中所做的那样。当然,这个不起作用 subprocess.call(['exit | theprogram

假设我想调用windows批处理文件中的程序。代码如下所示:

exit | theprogram arg1
我已经测试过了,效果非常好,非常感谢

现在,策略发生了重大变化,我必须在python脚本中调用该程序。为此,我使用子流程模块。我得到:

subprocess.call(['theprogram', arg1])
但是为了让它正常工作,我需要使用exit语句来处理它,就像我在批处理文件中所做的那样。当然,这个不起作用

subprocess.call(['exit | theprogram', arg1])
有人知道我如何将这个exit语句正确地传输到程序的输入端吗


非常感谢

指定
shell
关键字参数以通过shell解析调用:

subprocess.call('exit | theprogram %s' % arg1, shell=True)
当然,如果arg1包含空格或其他shell元字符,这将强制您手动引用它。通常情况下,
subprocess.call
不会精确地调用shell,因此您不必担心引用问题,但在您的情况下,它会将婴儿和洗澡水一起扔掉,因为您希望shell帮助管道操作员工作

一个更好的选择是允许
子流程
模块设置管道,它保留了这两个方面的优点,但要牺牲一些输入:

p1 = subprocess.Popen(["exit"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["theprogram", arg1], stdin=p1.stdout)
p1.stdout.close()
p2.communicate()

现在你不需要外壳,也不需要担心引用。
子流程
模块的更多使用示例见。

这不是对您问题的直接回答,但它解决了您思维中的一个谬误

您正试图指示sql*plus在完成脚本运行后退出。但这不是您的
exit | sqlplus…
管道构造所做的。它不只是将
echo
字符串作为输入传递给sqlplus。管道获取
exit
命令的输出(没有),并将其用作右侧命令的输入

正确的方法是使用
echo exit | sqlplus…

代码工作的原因是sqlplus检测到没有其他可用输入(输入缓冲区已关闭),因此它在执行脚本后立即退出。使用左侧任何不产生输出的命令都会得到相同的结果。例如:

(call )|sqlplus ...
另一种选择是将输入重定向到nul

<nul sqlplus ...

我知道这与这个问题没有严格的关系,但是为什么在批处理文件中使用
exit
命令呢?为什么不将
python程序arg1
?是的,请解释为什么需要将
exit
的不存在的输出导入程序。我怀疑您使用
会得到相同的结果,我想要执行的程序实际上是sqlplus。当您启动它时,它将保持打开状态,等待输入命令,直到您要求它退出(通过输入退出输入)。我不希望每次启动python脚本时都手动进入此出口,我希望它在完成后立即终止,因此管道:)不应该是
echo出口| sqlplus…
echo
用于将内容打印到标准输出。如果希望
sqlplus
接收字符串
exit
作为其输入,则应使用
echo exit | sqlplus
exit | sqlplus
之所以有效,是因为
exit
本质上是一个no-op,用于将文件结尾发送到
sqlplus
——正如@dbenham正确指出的那样。