为什么此 Python 子进程命令仅在 shell=True on Windows 时才有效?
Why does this Python subprocess command only work when shell=True on Windows?
我有一个涉及多个 subprocess.call
命令的 python 脚本。我在 Mac 上写了脚本,它运行得很好。我刚刚在 Windows 上尝试 运行 它,但我对错误感到困惑。
调用ImageMagick的命令如下returns"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命令)。
有趣的是,以下行在脚本的前面起作用(其中 file
、lat_crop1
和 croplat
是已定义的变量):
subprocess.call(['ffmpeg', '-loglevel', 'panic', '-i', file, '-vf', lat_crop1, '-n', croplat])
我阅读了 this SO question 并尝试了所有建议(shlex、我的命令的变体等),但我仍然得到相同的结果。
任何人都知道我如何修改该行以便它可以在没有 shell=True
的情况下工作?
另外,"exit status 4"是什么意思?我用 Google 搜索并阅读了很多文档,但一无所获。
编辑: 根据答案中提供的信息,我更改为对 subprocess.call(['mogrify', file1, '-resize', '200%', file1])
不起作用但在 [=50= 中成功运行的命令] 在 Windows 上。幸运的是 ImageMagick 提供 mogrify
作为 convert
.
的替代品
我怀疑你调用的是 C:\Windows\System32\convert.exe
(NTFS/FAT 分区转换器)而不是 imagemagick。
当shell=True
时,路径从imagemagick中找到convert.bat
或convert.cmd
脚本,但没有它,路径只能找到.exe
文件,即一个完全不同的程序,您会收到错误 4:参数无效。
在那种特殊情况下,即使是可执行文件,它也不起作用,因为 "wrong" convert
位于系统路径中。 shell=False
仅在系统路径中搜索 (python subprocess Popen environment PATH?)。所以不幸的是,名为 convert
的程序位于系统路径中。
尝试像这样显式添加 .bat
扩展名:
subprocess.call(['convert.bat', file1, '-resize', '200%', file1])
要知道哪些可执行文件可能是 运行 您可以键入:
where convert
在命令提示符下。
在您的情况下(一个可执行文件),可以通过将您想要的可执行文件的绝对路径传递给 运行 来解决这个问题。
另一种方法是 copy/rename ImageMagick convert
到 imconvert
。哪个程序调用自己 convert
并且无论如何都不会发生冲突?
或者在那种情况下,留下 shell=True
是合法的,并附上一条很好的评论,解释微软在系统路径中留下了一个令人困惑的(并且很少使用的 convert
程序供我们进入)
解决方案并不漂亮,至少有一些。
我有一个涉及多个 subprocess.call
命令的 python 脚本。我在 Mac 上写了脚本,它运行得很好。我刚刚在 Windows 上尝试 运行 它,但我对错误感到困惑。
调用ImageMagick的命令如下returns"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命令)。
有趣的是,以下行在脚本的前面起作用(其中 file
、lat_crop1
和 croplat
是已定义的变量):
subprocess.call(['ffmpeg', '-loglevel', 'panic', '-i', file, '-vf', lat_crop1, '-n', croplat])
我阅读了 this SO question 并尝试了所有建议(shlex、我的命令的变体等),但我仍然得到相同的结果。
任何人都知道我如何修改该行以便它可以在没有 shell=True
的情况下工作?
另外,"exit status 4"是什么意思?我用 Google 搜索并阅读了很多文档,但一无所获。
编辑: 根据答案中提供的信息,我更改为对 subprocess.call(['mogrify', file1, '-resize', '200%', file1])
不起作用但在 [=50= 中成功运行的命令] 在 Windows 上。幸运的是 ImageMagick 提供 mogrify
作为 convert
.
我怀疑你调用的是 C:\Windows\System32\convert.exe
(NTFS/FAT 分区转换器)而不是 imagemagick。
当shell=True
时,路径从imagemagick中找到convert.bat
或convert.cmd
脚本,但没有它,路径只能找到.exe
文件,即一个完全不同的程序,您会收到错误 4:参数无效。
在那种特殊情况下,即使是可执行文件,它也不起作用,因为 "wrong" convert
位于系统路径中。 shell=False
仅在系统路径中搜索 (python subprocess Popen environment PATH?)。所以不幸的是,名为 convert
的程序位于系统路径中。
尝试像这样显式添加 .bat
扩展名:
subprocess.call(['convert.bat', file1, '-resize', '200%', file1])
要知道哪些可执行文件可能是 运行 您可以键入:
where convert
在命令提示符下。
在您的情况下(一个可执行文件),可以通过将您想要的可执行文件的绝对路径传递给 运行 来解决这个问题。
另一种方法是 copy/rename ImageMagick convert
到 imconvert
。哪个程序调用自己 convert
并且无论如何都不会发生冲突?
或者在那种情况下,留下 shell=True
是合法的,并附上一条很好的评论,解释微软在系统路径中留下了一个令人困惑的(并且很少使用的 convert
程序供我们进入)
解决方案并不漂亮,至少有一些。