Why does this Python subprocess command only work if shell = True on Windows?

I have a python script that includes several subprocess.call commands. I wrote a script on Mac and it works fine. I just tried to run it on Windows and I am confused by the 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 a team to the following actions:

 subprocess.call(['convert', file1, '-resize', '200%', file1], shell=True) 

I am a little afraid to use shell=True due to warnings in the documentation.
I also need a command to work on both Mac and Windows, and I'm confused about why it won't work on Windows (I checked and the command works with Windows CMD).

Interestingly, the following line previously worked in a 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, my team options, etc.), but I still get the same result.

Does anyone know how I can change this line so that it can work without shell=True ?

Also, what does โ€œexit status 4โ€ mean? I figured out and read so much documentation, but found nothing about it.

EDIT: Based on the information provided in the answer, I changed a command that did not work on subprocess.call(['mogrify', file1, '-resize', '200%', file1]) and runs successfully in Python on Windows. Fortunately, ImageMagick provides mogrify as an alternative to convert .

+5
source share
1 answer

I suspect that you are calling C:\Windows\System32\convert.exe (NTFS / FAT partition converter) instead of imagemagick.

When shell=True , the path finds a convert.bat or convert.cmd script from imagemagick, but without it, the path can only find the .exe , which is a completely different program, and you get error 4: invalid parameter.

In this particular case, it does not work even with the executable file, since the "incorrect" convert is in the system path. shell=False only searches in system paths ( python subprocess Popen environment PATH? ). So the failure is that the program named convert is in the system path.

Try explicitly adding the .bat extension as follows:

 subprocess.call(['convert.bat', file1, '-resize', '200%', file1]) 

To find out which executables are likely to run, you can type:

 where convert 

on the command line.

In your case (an executable), which can be a workaround to pass the absolute path of the executable you want to run.

Another way would be to copy / rename ImageMagick convert to imconvert . What program calls itself convert and does not expect conflicts anyway?

Or in this case, itโ€™s legal to leave shell=True , with a good comment explaining that Microsoft left the confusing (and rarely used convert program in the system path so that we can enter it)

The solutions are not pretty, at least there are some.

+6
source

Source: https://habr.com/ru/post/1263356/


All Articles