为什么这个Python子进程命令仅在Windows上的shell = True时有效?

时间:2017-01-25 20:04:29

标签: python windows windows-7 imagemagick subprocess

我有一个涉及多个subprocess.call命令的python脚本。我在Mac上编写了脚本,它运行得很好。我刚尝试在Windows上运行它,我对错误感到困惑。

以下命令调用ImageMagick返回"退出状态4":

file1 = "D:/Temp/OCR_test/sample/images/crops/time_0011.png"
subprocess.call(['convert', file1, '-resize', '200%', file1])

将命令更改为以下作品:

subprocess.call(['convert', file1, '-resize', '200%', file1], shell=True)

由于文档中的警告,我对使用shell=True有点警惕。
我还需要命令在Mac和Windows上工作,我很困惑为什么它不能在Windows上工作(我检查过,命令确实可以使用Windows CMD)。

有趣的是,以下行在脚本的早期工作(其中filelat_crop1croplat是定义的变量):

subprocess.call(['ffmpeg', '-loglevel', 'panic', '-i', file, '-vf', lat_crop1, '-n', croplat])  

我读了this SO question并尝试了所有建议(shlex,我的命令的变化等等),但我仍然得到相同的结果。

任何人都知道如何修改该行,以便它可以在没有shell=True的情况下工作?

此外,"退出状态4"意思?我用Google搜索并阅读了大量文档,但没有发现任何相关信息。

编辑:根据答案中提供的信息,我更改为对subprocess.call(['mogrify', file1, '-resize', '200%', file1])无效的命令,并在Windows上的Python中成功运行。幸运的是,ImageMagick提供了mogrify作为convert的替代方案。

1 个答案:

答案 0 :(得分:7)

我怀疑你正在调用C:\Windows\System32\convert.exe(NTFS / FAT分区转换器)而不是imagemagick。

shell=True时,路径会从imagemagick中找到convert.batconvert.cmd脚本,但如果没有它,路径只能找到.exe文件,这完全是不同的程序,你得到错误4:参数无效。

在这种特殊情况下,即使使用可执行文件它也不起作用,因为“错误的”convert位于系统路径中。 shell=False仅在系统路径中搜索(python subprocess Popen environment PATH?)。因此,名为convert的程序位于系统路径中会带来好运。

尝试明确添加.bat扩展名,如下所示:

subprocess.call(['convert.bat', file1, '-resize', '200%', file1])

要知道可能运行哪些可执行文件,您可以输入:

where convert

在命令提示符下。

在您的情况下(可执行文件),可以通过传递您要运行的可执行文件的绝对路径来解决问题。

另一种方法是将ImageMagick convert复制/重命名为imconvert。哪个程序自称为convert并且不期待冲突?

或者在这种情况下,留下shell=True是合理的,并附有一个很好的评论,解释微软在系统路径中留下了令人困惑的(并且很少使用convert程序让我们进入)

解决方案并不漂亮,至少有一些。