4

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

这是我正在玩的一个简单的例子:

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

运行上面的代码时出现以下错误:

cat: <<DATA\nA String of Text\nDATA: No such file or directory

我做错了吗?这甚至可能吗?如果是这样,我将如何去做?


更新

只是想说这永远不应该在真正的 python 程序中执行,因为有更好的方法可以做到这一点。

4

4 回答 4

6

外壳“heredoc”支持是外壳功能。subprocess.Popen默认情况下不会通过 shell 运行你的命令,所以这种语法肯定行不通。

但是,由于无论如何您都在使用管道,因此无需使用 shell 的 heredoc 支持。只需将您的字符串写入您a刚刚开始的进程的标准输入管道。无论如何,这正是 shell 对heredoc 所做的事情。

你可以这样做Popen.communicate()

p.communicate(a)

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

于 2009-09-03T21:33:35.923 回答
4

正如其他人指出的那样,您需要在外壳中运行它。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
于 2009-09-03T21:58:11.573 回答
3

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

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

但这个概念本身是错误的。您应该使用 Python 功能而不是在 Python 脚本中调用 shell 脚本。

在这种特殊情况下,您应该使用 shell 的 heredoc 语法插入变量,因此您需要转义里面的所有文本a并确保其中没有DATA行。


对于 Python 等效项,我认为与此最接近的想法(假设您不想要只是print(a);-))是将变量的值传递给衍生进程的标准输入:

p = subprocess.Popen(["program", ...], stdin=subprocess.PIPE)
p.communicate(a)
于 2009-09-03T21:37:49.703 回答
0

从 Python 3.5 开始,您可以使用subprocess.run,如下所示:

subprocess.run(['cat'], input=b"A String of Text")
于 2021-05-12T15:57:07.070 回答