I have a python script that involves multiple subprocess.call
commands. I wrote the script on a Mac, and it runs perfectly. I just tried running it on Windows and I am baffled by an error.
The following command to call ImageMagick returns "exit status 4":
file1 = "D:/Temp/OCR_test/sample/images/crops/time_0011.png"
subprocess.call(['convert', file1, '-resize', '200%', file1])
Changing the command to the following works:
subprocess.call(['convert', file1, '-resize', '200%', file1], shell=True)
I'm a little wary of using shell=True
because of the warnings in the documentation.
I also need the command to work on both Mac and Windows, and I am confused as to why it wouldn't work on Windows (I checked and the command does work using Windows CMD).
Interestingly, the following line worked earlier in the script (where file
, lat_crop1
, and croplat
are defined variables):
subprocess.call(['ffmpeg', '-loglevel', 'panic', '-i', file, '-vf', lat_crop1, '-n', croplat])
I read this SO question and tried all the suggestions (shlex, variations of my command, etc...), but I still get the same result.
Anyone have any idea how I could modify that line so it can work without shell=True
?
Also, what does "exit status 4" mean? I Googled and read so much documentation but found nothing about it.
EDIT: Based on the information provided in the answer, I changed to the command that was not working to subprocess.call(['mogrify', file1, '-resize', '200%', file1])
and that runs successfully in Python on Windows. Luckily ImageMagick provides mogrify
as an alternative to convert
.
I suspect you're calling C:\Windows\System32\convert.exe
(NTFS/FAT partition converter) instead of imagemagick.
When shell=True
, the path finds the convert.bat
or convert.cmd
script from imagemagick, but without it, the path can only find the .exe
file, which is a completely different program, and you get error 4: invalid parameter.
In that particular case, it doesn't work even with an executable, because the "wrong" convert
is located in a system path. shell=False
only searches in system paths (python subprocess Popen environment PATH?). So that's bad luck that a program named convert
is located in the system path.
Try to explicitly add .bat
extension like this:
subprocess.call(['convert.bat', file1, '-resize', '200%', file1])
To know which executables are likely to be run you can type:
where convert
in a command prompt.
In your case (an executable), that could be workarounded by passing the absolute path of the executable you want to run.
Another way would be to copy/rename ImageMagick convert
to imconvert
. Which program calls itself convert
and doesn't expect conflicts anyway ?
Or in that case, it's legitimate to leave shell=True
, with a nice comment explaining that Microsoft left a confusing (and seldom used convert
program in a system path for us to trip into)
Solutions are not pretty, at least there are some.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With