webentwicklung-frage-antwort-db.com.de

OSError: [Errno 8] Ausführungsformatfehler

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

22
user3477108

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

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

1
rchang

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.

1
Drachenfels

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)
1
insti

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

  • hinzufügen von /bin/bash am Anfang des Befehls oder der Datei, die Sie sind
    das Problem mit, oder
  • hinzufügen von Shebang #!/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
0
Aseem Yadav