我完全清楚相关问题的存在,但所有问题都非常模糊,无法清楚地解释每一步的发生情况。提供的示例通常未经过测试,也未提供有关如何使其适应不同场景的信息。以下是问题以及Python的文档:
这基本上是我想要实现的,但在Python中:
curl http://asdf.com/89asdf.gif | convert -resize 80x80 - - | icat -k -
以下是我在几个小时之后将上述答案中的部分和部分内容进行坦诚相关的内容:
import requests
import subprocess
from subprocess import Popen, PIPE, STDOUT
url = 'http://asdf.com/89asdf.gif'
img = requests.get(url)
p1 = subprocess.Popen(['convert', '-resize', '80x80', '-', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p2 = subprocess.Popen(['icat', '-k', '-'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.communicate(img.content)
print p2.stdout
这是我的代码,这一次根据你的答案进行了改进:
import requests
from subprocess import Popen, PIPE, STDOUT
url = 'http://asdf.com/89asdf.gif'
img = requests.get(url)
p1 = Popen(['convert', '-resize', '80x80', '-', '-'], stdin=PIPE, stdout=PIPE)
p2 = Popen(['icat', '-k', '-'], stdin=p1.stdout, stdout=PIPE)
p1.stdin.write(img.content)
p1.stdin.close()
p1.stdout.close()
output = p2.communicate()[0]
print output
注意:icat
以256色终端输出图像。我已经设法在another question成功打印输出。一个典型的图像在icat
处理后的终端中看起来像这样:
请纠正我错在哪里,但这是我目前的理解:
p1.communicate(img.content)
:这会设置p1
的STDIN。p1
的STDIN是subprocess.PIPE
,这是p1.communicate(mg.content)
提供的。p2
的STDIN是p1
的STDOUT,即由convert
调整大小的图片。print
p2
的STDOUT,它应该是由icat
提供的ASCII颜色的图像。问题:
stdin=subprocess.PIPE
和stdin=PIPE
。有什么区别?有人可以解释一下这个过程中实际发生了什么以及我的代码有什么问题吗?整个管道业务必须比看起来更简单,我很想了解它是如何运作的。
答案 0 :(得分:1)
Q1。在subprocess.PIPE
或PIPE
的任何一种情况下,它们都引用相同的符号,即PIPE
模块中的subprocess
。以下是相同的:
# Version 1
import subprocess
proc = subprocess.Popen(['ls'], stdout=subprocess.PIPE)
output = proc.communicate()[0]
# Version 2
from subprocess import PIPE, Popen
proc = Popen(['ls'], stdout=PIPE)
output = proc.communicate()[0]
Q2。 communicate()
实际上做的是将输入发送到p1的STDIN流。尽管在调用Popen
构造函数时子进程确实存在且正在运行,但在您的特定情况下,convert
实用程序似乎在它实际通过STDIN接收内容之前不会执行任何操作。如果它是一个交互性较低的命令(例如ls
),则它不会等到communicate()
做任何事情。
更新的内容
在您的情况下,不要使用communicate
将输入发送到p1,而是尝试以下内容:
p1.stdin.write(img.content)
p1.stdin.close()
p1.stdout.close() # Protect against the busted pipe condition when p2 finishes before p1
output = p2.communicate()[0]
print output
看看你是否有更好的运气。
答案 1 :(得分:0)
Q1。它们都是subprocess.PIPE
....
Q2。你不必这样做就可以轻松做到
p1.stdin.write(img.content)
(事实上,这正是沟通的那部分所做的......)
使用了 communicate
,因为它会阻塞直到进程完成(在这种情况下,它的stdout可以被p2.stdin(可能是?))用,因为write
只是写入管道并且继续到文件