Hvorfor fungerer denne Python subprocess-kommando kun, når shell=True on Windows?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et python script, der involverer flere subprocess.call kommandoer. Jeg skrev scriptet på en Mac, og det kører perfekt. Jeg har lige prøvet at køre den på Windows, og jeg er forvirret af en fejl.


Følgende kommando for at ringe ImageMagick returnerer 'exit status 4':


file1 = "D:/Temp/OCR\_test/sample/images/crops/time\_0011.png"
subprocess.call(['convert', file1, '-resize', '200\%', file1])


Ændring af kommandoen til følgende værker:


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


Jeg er lidt forsigtig med at bruge shell=True på grund af advarslerne i dokumentationen.

Jeg har også brug for kommandoen til at arbejde på både Mac og Windows, og jeg er forvirret over, hvorfor det ikke ville fungere på Windows (jeg kontrollerede og kommandoen virker ved hjælp af Windows CMD).


Interessant nok har følgende linje arbejdet tidligere i scriptet (hvor file, lat\_crop1 og croplat er definerede variabler):


subprocess.call(['ffmpeg', '-loglevel', 'panic', '-i', file, '-vf', lat\_crop1, '-n', croplat])  


Jeg læste dette så spørgsmål og prøvede alle forslagene (shlex, variationer af min kommando osv. ..), men jeg får stadig det samme resultat.


Nogen har nogen ide om, hvordan jeg kunne ændre den linje, så det kan fungere uden shell=True?


Hvad betyder 'exit status 4' også? Jeg googlede og læste så meget dokumentation, men fandt ikke noget om det.


EDIT: På baggrund af de oplysninger, der blev givet i svaret, skiftede jeg til kommandoen, der ikke fungerede til subprocess.call(['mogrify', file1, '-resize', '200\%', file1]), og det kører korrekt i Python på Windows. Heldigvis giver ImageMagick mogrify som et alternativ til convert.

Bedste reference


Jeg formoder, at du ringer C:WindowsSystem32convert.exe (NTFS/FAT partition converter) i stedet for imagemagick.


Når shell=True finder stien convert.cmd eller convert.cmd -skriptet fra imagemagick, kan den kun finde filen .exe, der er et helt andet program uden det, og du får fejl 4: ugyldig parameter.


I det særlige tilfælde fungerer det ikke med en eksekverbar, fordi den 'forkerte' convert er placeret i en systemsti. shell=False søger kun i systemveje (python subprocess Popenvironment PATH?) . Så det er uheld, at et program med navnet convert er placeret i systembanen.


Prøv at eksplicit tilføje .bat udvidelse som denne:


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


For at vide, hvilke eksekverbare filer der sandsynligvis vil blive kørt, kan du skrive:


where convert


i en kommandoprompt.


I dit tilfælde (en eksekverbar), kan det løses ved at passere den absolutte sti for den eksekverbare, du vil køre.


En anden måde ville være at kopiere/omdøbe ImageMagick convert til imconvert. Hvilket program kalder sig convert og forventer ikke konflikter alligevel?


Eller i så fald er det legitimt at forlade shell=True med en flot kommentar, der forklarer, at Microsoft efterlod et forvirrende (og sjældent brugt convert program i en systemsti for at komme ind i)


Løsningerne er ikke smukke, i hvert fald er der nogle.