Popen冲突的可执行文件/path
我想使用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,并运行正确的可执行文件?
search一个程序是不平凡的。 我会明确指定convert.exe可执行文件的完整path 。
subprocess
CreateProcess
在Windows上使用CreateProcess
,甚至在%PATH%
任何其他目录之前查找system32
目录 :
…如果文件名不包含扩展名,则附加
.exe
。 因此,如果文件扩展名为.com,则此参数必须包含.com扩展名。 如果文件名以句点(。)结尾且没有扩展名,或者文件名包含path,则不会附加.exe。 如果文件名不包含目录path,则系统按以下顺序search可执行文件:
- 加载应用程序的目录。
- 父进程的当前目录。
- 32位Windows系统目录。 使用GetSystemDirectory函数获取此目录的path。
- 16位Windows系统目录。 没有获得这个目录的path的函数,但是它被search。 这个目录的名字是System。
- Windows目录。 使用GetWindowsDirectory函数获取此目录的path。
- PATH环境variables中列出的目录。 请注意,此函数不会searchApp Pathsregistry项指定的每个应用程序path。 要将这个每个应用程序path包含在search顺序中,请使用ShellExecute函数。
因此在这种情况下convert
等效于convert.exe
。 它首先查找包含sys.executable
文件的目录,例如C:\Python27
。 然后在当前目录中:从哪里启动Python脚本。 然后在system32
findconvert.exe
(文件系统工具,而不是imagemagick)。
你可以尝试从os.environ['PATH']
删除system32目录,它可能会抑制检查: Popen(cmd, env=no_system32_environ)
但它是脆弱的(比显式path差)。
Python bug跟踪器有一个相关的问题: “Subprocess在Windows上select错误的可执行文件”。
cmd.exe
(shell)使用不同的algorithm。 请参阅Windows如何在shell中查找input文件?
如果你设置shell=True
那么convert
程序的search顺序是:
-
convert
不是一个内部的shell命令 - 没有明确的path,search仍在继续
- search当前目录
- 按列出的顺序search由PATH环境variables指定的每个目录
%PATHEXT%
定义检查哪些文件扩展名以什么顺序检查,例如convert.com,convert.exe,convert.bat,convert.cmd,如果%PATHEXT%
是.com;.exe;.bat;.cmd
。
作为一种完全不同的方法,您可能需要尝试一下PythonMagick
,一个用于ImageMagick的Python包装器。 通过这种方式,你可以从Python中访问convert
的函数,而且不需要产生外部进程。
刚刚碰到这个自己。 在shell中运行php脚本可以访问shell $ PATH,而在Apache中运行则不会(至lessCygwin DLL / exe不是$ PATH)。
其次,在Windows平台上,在php中使用本地Windows符号C:/ dir / subdir / pgm,你将得到你所期望的。
因此,多平台代码需要切换/处理path,然后参考决策。