我想使用Popen从Python脚本中调用ImageMagick中的“convert”实用程序,如下所示:
Popen(["convert", input_path, "-flop", output_file_path])
(上面的例子简单地反转了图像水平)
问题是,当我在Windows中运行脚本时,它错误地调用Windows附带的convert.exe
实用程序将FAT分区转换为NTFS! (位于\ Windows \ system32)
现在,如果我在system32以外的任何目录中随机打开一个命令提示符并键入“convert”,它就会正确运行ImageMagick可执行文件。 所以,这意味着Popen自动查找system32。 我怎样才能让它不看在system32,并运行正确的可执行文件?
搜索一个程序是不平凡的。 我会明确指定convert.exe可执行文件的完整路径 。
subprocess
CreateProcess
在Windows上使用CreateProcess
,甚至在%PATH%
任何其他目录之前查找system32
目录 :
…如果文件名不包含扩展名,则附加
.exe
。 因此,如果文件扩展名为.com,则此参数必须包含.com扩展名。 如果文件名以句点(。)结尾且没有扩展名,或者文件名包含路径,则不会附加.exe。 如果文件名不包含目录路径,系统将按以下顺序搜索可执行文件:
因此在这种情况下convert
等效于convert.exe
。 它首先查找包含sys.executable
文件的目录,例如C:\Python27
。 然后在当前目录中:从哪里启动Python脚本。 然后在system32
找到convert.exe
(文件系统工具,而不是imagemagick)。
你可以尝试从os.environ['PATH']
删除system32目录,它可能会阻止检查它: Popen(cmd, env=no_system32_environ)
但它是脆弱的(比显式路径更糟糕)。
Python bug跟踪器有一个相关的问题: “Subprocess在Windows上选择错误的可执行文件”。
cmd.exe
(shell)使用不同的算法。 请参阅Windows如何在shell中查找输入文件?
如果你设置shell=True
那么convert
程序的搜索顺序是:
convert
不是一个内部的shell命令 %PATHEXT%
定义检查哪些文件扩展名以什么顺序检查,例如convert.com,convert.exe,convert.bat,convert.cmd,如果%PATHEXT%
是.com;.exe;.bat;.cmd
。
作为一种完全不同的方法,您可能需要尝试一下PythonMagick
,一个用于ImageMagick的Python包装器。 通过这种方式,你可以从Python中访问convert
的函数,而且不需要产生外部进程。
刚刚碰到这个自己。 在shell中运行php脚本可以访问shell $ PATH,而在Apache中运行则不会(至少Cygwin DLL / exe不是$ PATH)。
其次,在Windows平台上,在php中使用本地Windows符号C:/ dir / subdir / pgm,你将得到你所期望的。
因此,多平台代码需要切换/处理路径,然后参考决策。