13

我编写了一个 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消息,但图像通常似乎已下载并转换正常。但有时它们看起来很损坏,上面有黑色条纹(即使我使用的是最新版本的 ImageMagick),我认为这是因为在命令执行之前它们没有完全下载。

有什么办法可以对 Python 或subprocess:“在第一个命令确定成功完成之前不要运行第二个命令?”。我找到了这个问题,但看不到明确的答案!

4

2 回答 2

17

Normally, subprocess.call is blocking.

If you want non blocking behavior, you will use subprocess.Popen. In that case, you have to explicitly use Popen.wait to wait for the process to terminate.

See https://stackoverflow.com/a/2837319/2363712


BTW, in shell, if you wish to chain process you should use && instead of ; -- thus preventing the second command to be launched if the first one failed. In addition, you should test the subprocess exit status in your Python program in order to determine if the command was successful or not.

于 2013-06-19T11:37:23.877 回答
4

请参阅使用带有超时的模块“子进程”

不确定这是否是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.
于 2013-06-19T11:35:54.940 回答