Es fällt mir schwer, die Argumente in Subprozess.Popen zu analysieren. Ich versuche ein Skript auf meinem Unix-Server auszuführen. Die Skriptsyntax für Shell Prompt lautet wie folgt: /usr/local/bin/script hostname = <hostname> -p LONGLIST
. Egal wie ich es versuche, das Skript läuft nicht in subprocess.Popen
Das Leerzeichen vor und nach "=" ist obligatorisch.
import subprocess
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname = ', 'actual server name', '-p', 'LONGLIST'],Shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Das obige funktioniert nicht.
Und wenn ich Shell = False verwende, erhalte ich OSError: [Errno 8] Exec format error
OSError: [Errno 8] Exec format error
kann vorkommen, wenn sich oben im Shell-Skript keine Shebang-Linie befindet und Sie versuchen, das Skript direkt auszuführen. Hier ist ein Beispiel, das das Problem reproduziert:
>>> 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
Um das Problem zu beheben, fügen Sie einfach Shebang hinzu, wenn es sich beispielsweise um ein Shell-Skript handelt. voranstellen #!/bin/sh
oben in Ihrem Skript:
>>> with open('a','w') as f: f.write('#!/bin/sh\nexit 0')
...
>>> os.execl('./a', './a')
Es führt exit 0
ohne Fehler aus.
Auf POSIX-Systemen analysiert Shell die Befehlszeile, d. H. Ihr Skript sieht keine Leerzeichen um =
, z. B. wenn script
#!/usr/bin/env python
import sys
print(sys.argv)
dann in der Shell ausführen:
$ /usr/local/bin/script hostname = '<hostname>' -p LONGLIST
produziert:
['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
Hinweis: keine Leerzeichen um '='
. Ich habe <hostname>
in Anführungszeichen gesetzt, um die Umleitungs-Metazeichen <>
zu umgehen.
Um den Shell-Befehl in Python zu emulieren, führen Sie Folgendes aus:
from subprocess import check_call
cmd = ['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
check_call(cmd)
Hinweis: kein Shell=True
. Sie müssen <>
nicht entkommen, da keine Shell ausgeführt wird.
"Exec format error"
zeigt möglicherweise an, dass Ihre script
ein ungültiges Format hat. Führen Sie Folgendes aus:
$ file /usr/local/bin/script
um herauszufinden, was es ist. Vergleiche die Architektur mit der Ausgabe von:
$ uname -m
Hast du das probiert?
Out = subprocess.Popen('/usr/local/bin/script hostname = actual_server_name -p LONGLIST'.split(), Shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Gemäß dem entsprechenden Kommentar von @ J.F.Sebastian bearbeitet
Ich werde diesen Thread hijacken, um darauf hinzuweisen, dass dieser Fehler auch auftreten kann, wenn das Ziel von Popen nicht ausführbar ist. Hart gelernt, als ich aus Versehen eine perfekt ausführbare Binärdatei mit der Zip-Datei überschrieben hatte.
Wenn Sie denken, dass das Leerzeichen vor und nach "=" obligatorisch ist, versuchen Sie es als separates Element in der Liste.
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname', '=', 'actual server name', '-p', 'LONGLIST'],Shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Es wäre nicht falsch zu erwähnen, dass Pexpect
einen ähnlichen Fehler ausgibt
#python -c "import pexpect; p=pexpect.spawn('/usr/local/ssl/bin/openssl_1.1.0f version'); p.interact()"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/pexpect.py", line 430, in __init__
self._spawn (command, args)
File "/usr/lib/python2.7/site-packages/pexpect.py", line 560, in _spawn
os.execv(self.command, self.args)
OSError: [Errno 8] Exec format error
Hier hat die openssl_1.1.0f
-Datei am angegebenen Pfad den Befehl exec
angegeben und führt beim Aufruf die tatsächliche openssl-Binärdatei aus.
Normalerweise würde ich das nicht erwähnen, wenn ich nicht die eigentliche Ursache habe, aber dieses Problem war vorher nicht da. Wenn das ähnliche Problem nicht gefunden werden kann, ist die beste Erklärung dafür die gleiche, die von @jfs oben bereitgestellt wird.
was für mich funktioniert hat, ist beides
/bin/bash
am Anfang des Befehls oder der Datei, die Sie sind#!/bin/sh
als erste Zeile.zum Beispiel.
#python -c "import pexpect; p=pexpect.spawn('/bin/bash /usr/local/ssl/bin/openssl_1.1.0f version'); p.interact()"
OpenSSL 1.1.0f 25 May 2017