我写了一个Python脚本,下载和转换许多图像,使用wget,然后ImageMagick通过链接的subprocess
调用:
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。但有时它们看起来会损坏,上面有黑色条纹(尽管我使用的是最新版本的ImageMagick),我认为这是因为它们在命令执行之前没有完全下载。
我是否可以对Python或subprocess
说:"在第一个命令绝对成功完成之前不要运行第二个命令?"我发现了这个问题,但找不到明确的答案!
正常情况下, subprocess.call
阻塞
subprocess.Popen
。在这种情况下,您必须显式地使用Popen.wait
来等待进程终止。
见https://stackoverflow.com/a/2837319/2363712
顺便说一句,在shell中,如果您希望链接进程,您应该使用&&
而不是;
——这样可以防止在第一个命令失败时启动第二个命令。此外,您应该在Python程序中测试子进程退出状态,以确定命令是否成功。
参见Using module 'subprocess'与超时
不确定这是否是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.