如何通过管道将子进程调用传递给文本文件?

Posted

技术标签:

【中文标题】如何通过管道将子进程调用传递给文本文件?【英文标题】:How do I pipe a subprocess call to a text file? 【发布时间】:2011-06-18 21:36:21 【问题描述】:
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"])

现在我有一个可以运行的脚本。当我运行它并到达这一行时,它会开始打印内容,因为 run.sh 中有打印内容。

我如何也将其通过管道传输到文本文件? (如果可能,还可以打印)

【问题讨论】:

【参考方案1】:

popen 的选项可以在call 中使用

args, 
bufsize=0, 
executable=None, 
stdin=None, 
stdout=None, 
stderr=None, 
preexec_fn=None, 
close_fds=False, 
shell=False, 
cwd=None, 
env=None, 
universal_newlines=False, 
startupinfo=None, 
creationflags=0

所以...

myoutput = open('somefile.txt', 'w')
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"], stdout=myoutput)

然后你可以用myoutput做你想做的事

此外,您可以像这样更接近管道输出。

dmesg | grep hda

应该是:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

python manual page 上有很多可爱、有用的信息。

【讨论】:

【参考方案2】:

如果要将输出写入文件,可以使用stdout-参数subprocess.call

两者都需要

None(默认情况下,stdout 继承自父级(您的脚本)) subprocess.PIPE(允许您从一个命令/进程通过管道传输到另一个) 文件对象或文件描述符(您想要的,将输出写入文件)

你需要用open之类的东西打开一个文件,并将对象或文件描述符整数传递给call

f = open("blah.txt", "w")
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"], stdout=f)

我猜任何有效的类似文件的对象都可以工作,比如套接字(喘气:)),但我从未尝试过。

正如 marcog 在 cmets 中提到的,您可能还希望重定向 stderr,您可以使用 stderr=subprocess.STDOUT 将其重定向到与 stdout 相同的位置。上面提到的任何值都可以,你可以重定向到不同的地方。

【讨论】:

为什么 subprocess.call(["echo", "1", ">>", "t.txt"]) 不起作用? @Goldname 你需要一个外壳来做重定向,所以:subprocess.call(["echo", "1", ">>", "t.txt"], shell=True) 应该可以工作。 @WesMason 谢谢,但我认为 subprocess.call 的工作方式基本上类似于复制粘贴到 shell 中? @Goldname 不,子进程中的所有内容都依赖于底层 Popen 类,它打开一个进程,shell=True 将强制进程在系统默认 shell 中执行(例如 /bin/sh on POSIX系统,通常是 bash 或 dash),这样更安全,因为您不会对 shell 提供的所有额外功能开放(一个完整的编程语言本身,如果传入用户提供的数据,它有自己的漏洞) .如果您将任何可能的脏数据传递给子shell,还请查看shlex.quote 我们是否也应该在完成后关闭文件?这将在我们完成后关闭文件:with open("blah.txt","w") as f: subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml", "/tmp/video_xml"], stdout=f) @Skurmedel

以上是关于如何通过管道将子进程调用传递给文本文件?的主要内容,如果未能解决你的问题,请参考以下文章

获取通过管道传递给命令的文件的当前行

如何在管道上使用 WriteFile 修复乱码文本?

Linux中进程间传递文件描述符的方法

管道的概念和一些用法 初步认识三剑客

消息队列和管道的区别

Linux之重定向管道