2014-12-22 10 views
18

Sto riscontrando delle difficoltà nel parsing degli argomenti del sottoprocesso.Popen. Sto cercando di eseguire uno script sul mio server Unix. La sintassi dello script quando si esegue il prompt della shell è la seguente: /usr/local/bin/script hostname = <hostname> -p LONGLIST. Non importa come provo, lo script non è in esecuzione nel sottoprocesso.PopenOSErrore: [Errno 8] Errore di formato Exec

Lo spazio prima e dopo "=" è obbligatorio.

import subprocess 
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname = ', 'actual server name', '-p', 'LONGLIST'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 

Quanto sopra non funziona.

e quando uso shell = False, ottengo OSError: [Errno 8] Exec format error

+0

Wild guess: prova ''nomehost = nome server effettivo'' anziché' 'nomehost =', 'nome server effettivo'' – Kevin

+0

In base a come dici di eseguirlo al prompt, sembra che' hostname' sia un argomento e '=' è un argomento separato, che è piuttosto strano. Sei sicuro che ci siano degli spazi attorno a '='? –

+0

ciao Bryan, sì, ci deve essere spazio. Lo script accetta l'argomento del tipo chiave = valore. – user3477108

risposta

1

Hai provato questo?

Out = subprocess.Popen('/usr/local/bin/script hostname = actual_server_name -p LONGLIST'.split(), shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 

A cura per il commento apt da @ J.F.Sebastian

+0

Ciao Rchang, grazie per il tuo feedback. Non funziona. Il mio script richiede spazio prima e dopo "=". La tua soluzione lo fornisce? – user3477108

+0

Questo dovrebbe funzionare correttamente con questo comando ma non è una buona soluzione per scopi generali perché non consente di evitare gli spazi incorporati. Il metodo 'shlex.split' potrebbe essere una scelta migliore. – tdelaney

+0

[non utilizzare shell = True e un argomento lista insieme] (http://stackoverflow.com/questions/27606653/python-subprocess-popen-woes#comment43638333_27607257) – jfs

1

Se si pensa che lo spazio prima e dopo "=" è obbligatoria, provare come voce separata nella lista.

Out = subprocess.Popen(['/usr/local/bin/script', 'hostname', '=', 'actual server name', '-p', 'LONGLIST'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
+0

downvoted. [Non usare 'shell = True' e un argomento lista] (http://bugs.python.org/issue21347) (si tratta di un errore in * molti * casi). – jfs

57

OSError: [Errno 8] Exec format error può accadere se non c'è una linea shebang nella parte superiore dello script di shell e si sta tentando di eseguire direttamente lo script. Ecco un esempio che riproduce il problema:

>>> with open('a','w') as f: f.write('exit 0') # create the script 
... 
>>> import os 
>>> os.chmod('a', 0b111101101) # rwxr-xr-x make it executable      
>>> os.execl('./a', './a')  # execute it            
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/os.py", line 312, in execl 
    execv(file, args) 
OSError: [Errno 8] Exec format error 

per risolvere il problema, è sufficiente aggiungere la baracca per esempio, se si tratta di uno script di shell; anteporre #!/bin/sh nella parte superiore dello script:

>>> with open('a','w') as f: f.write('#!/bin/sh\nexit 0') 
... 
>>> os.execl('./a', './a') 

esegue exit 0 senza errori.


Sui sistemi POSIX, shell analizza l'esempio da riga di comando, lo script non vedrà spazi intorno = ad esempio, se è script:

#!/usr/bin/env python 
import sys 
print(sys.argv) 

poi eseguirlo nella shell:

$ /usr/local/bin/script hostname = '<hostname>' -p LONGLIST 

produce:

['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST'] 

Nota: senza spazi intorno a '='. Ho aggiunto le citazioni attorno allo <hostname> per evitare i metacaratteri di reindirizzamento <>.

per emulare il comando di shell in Python, eseguire:

from subprocess import check_call 

cmd = ['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST'] 
check_call(cmd) 

Note: no shell=True. E non è necessario sfuggire a <> perché non viene eseguita alcuna shell.

"Exec format error" potrebbe indicare che il script ha formato non valido, eseguire:

$ file /usr/local/bin/script 

per scoprire di cosa si tratta.Confrontare l'architettura con l'uscita di:

$ uname -m 
+0

Devo aver cancellato per errore parte della mia shebang in vim ... Ero perso fino al tuo post. Grazie. –

+0

@nbro: sbagliato. Guarda il primo esempio di codice nella mia risposta. Otterrai OSError se non ci sono shebang. È lo stesso errore di [tua domanda] (http://stackoverflow.com/q/35216720/4279). Non c'è nessun errore se si esegue il comando nella shell (no shebang significa: "esegui come script di shell" in questo caso). 'subprocess.check_output()' non esegue la shell di default - nessuna funzione di sottoprocesso esegue la shell a meno che tu non chieda esplicitamente (se non lo sapevi, chiedi di riaprire la tua domanda). – jfs

1

io dirottare questo thread sottolineare che questo errore può anche accadere quando il bersaglio di Popen non è eseguibile. Imparato in modo difficile quando per caso ho dovuto scavalcare un file binario perfettamente eseguibile con file zip.

+0

è per questo che la mia risposta suggerisce il comando 'file your-executable' (mostrerebbe che hai un archivio zip). Anche se alcuni archivi zip possono essere eseguibili corretti, ad esempio, [python: i file zip eseguibili possono includere file di dati?] (Https://stackoverflow.com/q/5355694/4279) – jfs

Problemi correlati