6

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.

Community
  • 1
  • 1
Evan
  • 1,960
  • 4
  • 26
  • 54

1 Answers1

8

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.

Community
  • 1
  • 1
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • 3
    [`CreateProcess`](https://msdn.microsoft.com/en-us/library/ms682425) always searches system directories before `PATH` and tries appending ".EXE". The cmd shell, on the other hand, does its own search of `PATH`, and tries appending the extensions in `PATHEXT`, and then it calls `CreateProcess` with the fully-qualified path of the file that it finds. – Eryk Sun Jan 25 '17 at 20:27
  • @eryksun: found this: http://stackoverflow.com/questions/5658622/python-subprocess-popen-environment-path. Your explanation is the best one. I'm editing. – Jean-François Fabre Jan 25 '17 at 20:29
  • That's really interesting and great to know about other `convert` programs. Adding the full path in the `subprocess` command worked. Thank you for the suggestion. Also changing the ImageMagick module to `imconvert` could be a good idea. I agree that it's weird they would use such a generic name. – Evan Jan 25 '17 at 20:33
  • 1
    I suggest they call it `dir` the next time :) most interesting question today by far. Just when I thought I knew windows very well... – Jean-François Fabre Jan 25 '17 at 20:34