Python子进程:在开始下一个命令之前等待命令完成?

时间:2013-06-19 11:29:35

标签: python imagemagick subprocess imagemagick-convert

我编写了一个Python脚本,使用wget下载并转换许多图像,然后使用链接subprocess调用ImageMagick:

for img in images: 
  convert_str = 'wget -O  ./img/merchant/download.jpg %s; ' % img['url'] 
  convert_str += 'convert ./img/merchant/download.jpg -resize 110x110 ' 
  convert_str += ' -background white -gravity center -extent 110x110' 
  convert_str += ' ./img/thumbnails/%s.jpg' % img['id']
  subprocess.call(convert_str, shell=True)

如果我在命令行手动运行convert_str的内容,它似乎没有任何错误,但如果我运行脚本使其重复执行,它有时会给我以下输出:

--2013-06-19 04:01:50--  
http://www.lkbennett.com/medias/sys_master/8815507341342.jpg
Resolving www.lkbennett.com... 157.125.69.163
Connecting to www.lkbennett.com|157.125.69.163|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22306 (22K) [image/jpeg]
Saving to: `/home/me/webapps/images/m/img/merchant/download.jpg'

 0K .......... .......... .                               100% 1.03M=0.02s

2013-06-19 04:01:50 (1.03 MB/s) - 
`/home/annaps/webapps/images/m/img/merchant/download.jpg' saved [22306/22306]

/home/annaps/webapps/images/m/img/merchant/download.jpg 
[Errno 2] No such file or directory: 
' /home/annaps/webapps/images/m/img/merchant/download.jpg'

奇怪的是,尽管有No such file or directory消息,但图像通常似乎已下载并转换为OK。但偶尔它们会看起来很糟糕,black stripes就可以了(虽然我使用的是最新版本的ImageMagick),我认为这是因为它们在执行命令之前没有完全下载。

我有什么方法可以对Python或subprocess说:“在第一个命令成功完成之前,不要运行第二个命令吗?”。我found this question但看不清楚答案!

2 个答案:

答案 0 :(得分:12)

通常subprocess.call正在阻止。

如果您想要非阻止行为,您将使用subprocess.Popen。在这种情况下,您必须明确使用Popen.wait来等待进程终止。

请参阅https://stackoverflow.com/a/2837319/2363712


BTW,在shell中,如果你想进行链式处理,你应该使用&&而不是; - 从而防止第一个命令在第一个命令失败时启动。此外,您应该在Python程序中测试子进程退出状态,以确定命令是否成功。

答案 1 :(得分:2)

请参阅Using module 'subprocess' with timeout

不确定这是否是proper方式,但这就是我实现这一目标的方法:

import subprocess
from threading import Thread

def call_subprocess(cmd):
    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = proc.communicate()
    if err:
        print err

thread = Thread(target=call_subprocess, args=[cmd])
thread.start()
thread.join() # waits for completion.