带有heredocs的Python子进程

发布于 2024-08-04 06:14:15 字数 439 浏览 2 评论 0原文

我正在使用 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 程序中执行,因为有更好的方法可以做到这一点。

I was playing around with Python's subprocess module, trying a few examples but I can't seem to get heredoc statements to work.

Here is the trivial example I was playing with:

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

I get the following error when I run the code above:

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

Am I doing it wrong? Is this even possible? If so how would I go about doing it?


Update

Just wanted to say that this should never be performed in a real python program because there are better ways of doing this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帥小哥 2024-08-11 06:14:15

shell“heredoc”支持是一项 shell 功能。默认情况下,subprocess.Popen 不会通过 shell 运行您的命令,因此这种语法肯定不起作用。

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

您可以使用 Popen.communicate() 来完成此操作

p.communicate(a)

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

The shell "heredoc" support is a shell feature. subprocess.Popen does not run your command through the shell by default, so this syntax certainly won't work.

However, since you're using pipes anyway, there isn't any need to use the heredoc support of the shell. Just write your string a to the stdin pipe of the process you just started. This is exactly what the shell would do with the heredoc anyway.

You can do this with Popen.communicate():

p.communicate(a)

The return value of the communicate() function contains the output of the process (in two streams, see the docs).

儭儭莪哋寶赑 2024-08-11 06:14:15

正如其他人指出的那样,您需要在 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

As others have pointed out, you need to run it in a shell. Popen makes this easy with a shell=True argument. I get the following output:

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

>>> p.wait()
0
雨的味道风的声音 2024-08-11 06:14:15

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

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

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

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


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

p = subprocess.Popen(["program", ...], stdin=subprocess.PIPE)
p.communicate(a)

You're passing shell syntax as an arguments to cat program. You can try to do it like that:

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

But the concept itself is wrong. You should use Python features instead of calling shell scripts inside your python scripts.

And in this particular case you should that shell's heredoc syntax interpolates variables, so you'll need to escape all the text inside a and make sure there's no DATA line in it.


For Python equivalent, I think the closest idea to this (assuming you don't want just print(a) ;-)) is passing the value of the variable to stdin of a spawned process:

p = subprocess.Popen(["program", ...], stdin=subprocess.PIPE)
p.communicate(a)
感性 2024-08-11 06:14:15

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

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

As of Python 3.5 you can use subrocess.run as in:

subprocess.run(['cat'], input=b"A String of Text")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文