带有heredocs的Python子进程

带有heredocs的Python子进程,python,subprocess,heredoc,Python,Subprocess,Heredoc,我在玩弄Python的子流程模块,尝试了一些示例,但我似乎无法让heredoc语句正常工作 下面是我正在玩的一个小例子: import subprocess a = "A String of Text" p = subprocess.Popen(["cat", "<<DATA\n" + a + "\nDATA"]) 导入子流程 a=“一个文本字符串” p=subprocess.Popen([“cat”,“shell“herdoc”支持是一个shell功能。subprocess.Po

我在玩弄Python的子流程模块,尝试了一些示例,但我似乎无法让heredoc语句正常工作

下面是我正在玩的一个小例子:

import subprocess
a = "A String of Text"
p = subprocess.Popen(["cat", "<<DATA\n" + a + "\nDATA"])
导入子流程
a=“一个文本字符串”
p=subprocess.Popen([“cat”,“shell“herdoc”支持是一个shell功能。
subprocess.Popen
默认情况下不会通过shell运行命令,因此此语法肯定不起作用

但是,由于您使用的是管道,因此不需要使用shell的heredoc支持。只需将字符串
a
写入刚刚启动的进程的stdin管道即可。这正是shell使用heredoc所做的

您可以通过以下方式执行此操作:


communicate()
函数的返回值包含进程的输出(在两个流中,请参阅文档)。

您将shell语法作为参数传递给
cat
程序。您可以尝试这样做:

p = subprocess.Popen(["sh", "-c", "cat <<DATA\n" + a + "\nDATA"])

正如其他人所指出的,您需要在shell中运行它。Popen使用shell=True参数简化了这一过程。我得到以下输出:

>>> import subprocess
>>> a = "A String of Text"
>>> p = subprocess.Popen("cat <<DATA\n" + a + "\nDATA", shell=True)
>>> A String of Text

>>> p.wait()
0
导入子流程 >>>a=“一个文本字符串”
>>>p=subprocess.Popen(“cat从Python 3.5开始,您可以在中使用:


这是一个很有帮助的答案。如果你能以Python的方式给出代码建议,那就更好了。正如我在问题中所说的,这只是在玩弄子流程,我永远不会在Python中调用
cat
。这是出于好奇,更适合在实际代码中使用。“您应该使用Python功能,而不是在Python脚本中调用shell脚本。"Python中并非所有的shell功能都可用。一个herdeoc可以提供给许多没有Python接口的不同类型的程序,并且可以用Python动态生成herdeoc内容。@user5359531,我添加了一个简单的例子。我不太明白shell参数的作用。文档很好地解释了发生了什么当您将其设置为true时,但设置为false时不会太多。当
shell
参数为
false
时,
子流程
模块直接执行您指定的程序(在您的情况下,可能是
/bin/cat
),并使用调用
Popen()中指定的参数
。没有对shell字符(如重定向或管道)进行解释,程序会准确地看到您发送的内容。这就是为什么
cat
说找不到名称以
开头的文件的原因感谢您的解释,澄清了几件事。
p = subprocess.Popen(["sh", "-c", "cat <<DATA\n" + a + "\nDATA"])
p = subprocess.Popen(["program", ...], stdin=subprocess.PIPE)
p.communicate(a)
>>> import subprocess
>>> a = "A String of Text"
>>> p = subprocess.Popen("cat <<DATA\n" + a + "\nDATA", shell=True)
>>> A String of Text

>>> p.wait()
0
subprocess.run(['cat'], input=b"A String of Text")