2014-12-22 13 views
18

Mam trudny czas analizowania argumentów do podprocesu.Popen. Próbuję wykonać skrypt na moim serwerze Unix. Składnia skryptu podczas uruchamiania w wierszu polecenia powłoki jest następująca: /usr/local/bin/script hostname = <hostname> -p LONGLIST. Bez względu na to, jak próbuję, skrypt nie działa w podprocesie.PopenOSError: [Errno 8] Błąd formatu Exec

Przestrzeń przed i po "=" jest obowiązkowa.

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

Powyższe nie działa.

A kiedy używam shell = False, mam OSError: [Errno 8] Exec format error

+0

Wild guess: spróbuj ''hostname = nazwa rzeczywistego serwera'' zamiast'' hostname = ',' rzeczywista nazwa serwera'' – Kevin

+0

Na podstawie tego, jak mówisz, że uruchomiłeś to po znaku zachęty, wygląda na to, że 'hostname' jest jeden argument i '=' to osobny argument, co jest dość dziwne. Czy na pewno są spacje wokół '='? –

+0

hi Bryan, tak, musi być miejsce. Skrypt przyjmuje argument typu klucz = wartość. – user3477108

Odpowiedz

1

Próbował pan jest?

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

Zmieniano za apt komentarzu od @ J.F.Sebastian

+0

Cześć Rchang, dziękuję za twoją opinię. To nie działa. Mój skrypt wymaga spacji przed i po "=". Czy Twoje rozwiązanie to zapewnia? – user3477108

+0

To powinno działać poprawnie na tym poleceniu, ale nie jest dobrym rozwiązaniem ogólnego przeznaczenia, ponieważ nie pozwala na ucieczkę przestrzeni osadzonych. Metoda 'shlex.split' może być lepszym wyborem. – tdelaney

+0

[nie używaj powłoki = True i argumentu razem] (http://stackoverflow.com/questions/27606653/python-subprocess-popen-woes#comment43638333_27607257) – jfs

1

Jeśli uważasz, że przestrzeń przed i po „=” jest obowiązkowe, spróbuj go jako osobna pozycja na liście.

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

odrzucone. [Nie używaj 'shell = True' i argumentu listy] (http://bugs.python.org/issue21347) (jest to błąd w * większości * przypadków). – jfs

57

OSError: [Errno 8] Exec format error może się zdarzyć, jeśli nie ma linii shebang na górze skryptu powłoki i staramy się wykonać skrypt bezpośrednio. Oto przykład, który odtwarza problem:

>>> 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 

Aby to naprawić, wystarczy dodać shebang np. Jeśli jest to skrypt powłoki; poprzedzić #!/bin/sh na górze skryptu:

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

Wykonuje exit 0 bez żadnych błędów.


W systemach POSIX, powłoka przetwarza czyli linia poleceń, skrypt nie będzie widać przestrzenie wokół = przykład jeśli script jest:

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

następnie uruchomić go w powłoce:

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

produkuje:

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

Uwaga: bez spacji około '='. Dodałem cytaty o numerze <hostname>, aby uniknąć metaznaków przekierowania <>.

emulować polecenie powłoki w Pythonie, uruchom:

from subprocess import check_call 

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

Uwaga: nie shell=True. I nie musisz uciec <>, ponieważ nie jest uruchamiana żadna powłoka.

"Exec format error" może wskazywać, że script ma nieprawidłowy format, uruchom:

$ file /usr/local/bin/script 

aby dowiedzieć się, co to jest.Porównaj architekturę z wyjściem:

$ uname -m 
+0

Musiałem przypadkowo usunąć część mojego shebangu w vim ... Byłem zagubiony aż do twojego postu. Dzięki. –

+0

@nbro: źle. Spójrz na pierwszy przykład kodu w mojej odpowiedzi. Dostaniesz OSError, jeśli nie ma żadnego shebangu. Jest to ten sam błąd, co w [Twoje pytanie] (http://stackoverflow.com/q/35216720/4279). Nie ma błędu, jeśli uruchomisz polecenie w powłoce (no shebang oznacza: "uruchom jako skrypt powłoki" w tym przypadku). 'subprocess.check_output()' nie uruchamia powłoki domyślnie - żadne funkcje podprocesu nie uruchamiają powłoki, chyba że zapytasz jawnie (jeśli tego nie wiesz, poproś o ponowne otwarcie pytania). – jfs

1

będę HijackThis wątek podkreślić, że ten błąd może się zdarzyć, gdy celem POPEN nie jest wykonywalny. Nauczyłem się tego, kiedy przez przypadek przesłoniłem doskonale wykonywalny plik binarny z plikiem zip.

+0

dlatego moja odpowiedź zaleca polecenie 'file your-executable' (pokazałoby, że masz archiwum zip). Chociaż niektóre archiwa zip mogą być również właściwymi plikami wykonywalnymi, np. [Python: czy pliki wykonywalne zip mogą zawierać pliki danych?] (Https://stackoverflow.com/q/5355694/4279) – jfs

Powiązane problemy