我正在使用Python的子进程模块,尝试一些示例,但我似乎无法使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程序中执行,因为有更好的方法可以做到这一点。
答案 0 :(得分:4)
shell“heredoc”支持是一个shell功能。 <{1}}默认情况下不会通过shell运行命令,因此这种语法肯定不起作用。
但是,由于您无论如何都在使用管道,因此无需使用shell的heredoc支持。只需将字符串subprocess.Popen
写入刚刚启动的进程的stdin管道。无论如何,这正是shell对heredoc的作用。
您可以使用Popen.communicate()
执行此操作:
a
p.communicate(a)
函数的返回值包含进程的输出(在两个流中,请参阅文档)。
答案 1 :(得分:4)
正如其他人所指出的,你需要在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
答案 2 :(得分:3)
您将shell语法作为cat
程序的参数传递。您可以尝试这样做:
p = subprocess.Popen(["sh", "-c", "cat <<DATA\n" + a + "\nDATA"])
但这个概念本身是错误的。您应该使用Python功能,而不是在python脚本中调用shell脚本。
在这种特殊情况下,你应该使用shell的heredoc语法插入变量,因此你需要转义a
中的所有文本,并确保其中没有DATA
行。
对于Python等价物,我认为最接近这个(假设你不想只是print(a)
;-))是将变量的值传递给生成过程的stdin:
p = subprocess.Popen(["program", ...], stdin=subprocess.PIPE)
p.communicate(a)
答案 3 :(得分:0)
从 Python 3.5 开始,您可以像这样使用 subrocess.run:
subprocess.run(['cat'], input=b"A String of Text")