为什么这个Python子进程命令只有在Windows上使用shell=True才有效?

7

我有一个Python脚本,其中涉及多个subprocess.call命令。我在Mac上编写的脚本运行得很完美。我刚刚尝试在Windows上运行它,但却遇到了一个错误。

以下调用ImageMagick的命令返回"exit status 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])  

我看了这篇SO问题并尝试了各种建议(shlex、命令的变化等等),但我还是得到了相同的结果。

有没有人有任何想法,如何修改那行代码,使它可以在不使用shell=True的情况下工作?

此外,“退出状态4”是什么意思?我谷歌搜索并阅读了很多文档,但没有找到相关内容。

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


convert 命令是什么?ImageMagick? - Blorgbeard
是的,我忘记提到了,它是ImageMagick。 它可以在命令行中工作。 - Evan
你能否从命令行中输入 where convert - Jean-François Fabre
不知道那个命令!它返回 C:\Program Files\ImageMagick-6.9.2-Q16-HDRI\convert.exeC:\Windows\System32\convert.exe。我现在看到这可能会产生问题了。 - Evan
1个回答

8
我怀疑你正在调用 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,并注释说明Microsoft在系统路径中留下了一个混淆(并且很少使用的convert程序)供我们绊倒。

解决方案并不美观,但至少有一些。


3
CreateProcess 在查找文件时,始终会先搜索系统目录,然后再搜索 PATH 环境变量,并尝试附加 ".EXE" 扩展名。而 cmd shell 则会自行搜索 PATH 环境变量,并尝试附加 PATHEXT 中的扩展名,然后调用 CreateProcess 并传入找到的文件的完全限定路径。 - Eryk Sun
@eryksun:找到了这个链接:https://dev59.com/jm035IYBdhLWcg3wC7cR。你的解释是最好的。我正在进行编辑。 - Jean-François Fabre
这真的很有趣,了解其他“convert”程序也很棒。在“subprocess”命令中添加完整路径是有效的。感谢您的建议。另外,将ImageMagick模块更改为“imconvert”可能是个好主意。我同意他们使用如此通用的名称很奇怪。 - Evan
1
我建议他们下次把它叫做“dir” :) 今天迄今为止最有趣的问题。就在我以为自己非常了解Windows的时候... - Jean-François Fabre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接