web-dev-qa-db-fra.com

OSError: [Errno 8] Erreur de format Exec

J'ai du mal à analyser les arguments de subprocess.Popen. J'essaye d'exécuter un script sur mon serveur Unix. La syntaxe du script lors de l'exécution sur l'invite du shell est la suivante: /usr/local/bin/script hostname = <hostname> -p LONGLIST. Peu importe comment j'essaie, le script ne s'exécute pas dans subprocess.Popen

L'espace avant et après "=" est obligatoire.

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

Ce qui précède ne fonctionne pas.

Et quand j'utilise Shell = False, je reçois OSError: [Errno 8] Exec format error

22
user3477108

OSError: [Errno 8] Exec format error peut arriver s'il n'y a pas de ligne Shebang en haut du script Shell et si vous essayez d'exécuter le script directement. Voici un exemple qui reproduit le problème:

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

Pour résoudre ce problème, ajoutez simplement Shebang, par exemple, s’il s’agit d’un script Shell; insérez #!/bin/sh en haut de votre script:

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

Il exécute exit 0 sans aucune erreur.


Sur les systèmes POSIX, Shell analyse la ligne de commande, c’est-à-dire que votre script ne verra aucun espace autour de =, par exemple si script est:

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

puis l'exécuter dans le shell:

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

produit:

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

Remarque: pas d'espace autour de '='. J'ai ajouté des guillemets autour de <hostname> pour échapper aux métacaractères de redirection <>.

Pour émuler la commande Shell en Python, exécutez:

from subprocess import check_call

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

Remarque: non Shell=True. Et vous n'avez pas besoin d'échapper à <> car aucun shell n'est exécuté.

"Exec format error" peut indiquer que votre script a un format invalide, exécutez:

$ file /usr/local/bin/script

pour savoir ce que c'est. Comparez l'architecture avec la sortie de:

$ uname -m
66
jfs

Avez-vous essayé cela?

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

Edité par le commentaire d'apt de @ J.F.Sebastian

1
rchang

Je vais détourner ce fil pour signaler que cette erreur peut également se produire lorsque la cible de Popen n'est pas exécutable. Je l'ai appris de manière difficile quand, par accident, j'ai remplacé un fichier binaire parfaitement exécutable par un fichier Zip.

1
Drachenfels

Si vous pensez que l'espace avant et après "=" est obligatoire, essayez-le séparément dans la liste.

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

Il ne serait pas faux de mentionner que Pexpect jette une erreur similaire

#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

Ici, le fichier openssl_1.1.0f situé dans le chemin spécifié contient la commande exec qui y est spécifiée et exécute le fichier binaire openssl lorsqu'il est appelé.

D'habitude, je ne le mentionne pas à moins d'en avoir la cause fondamentale, mais ce problème n'existait pas auparavant. Impossible de trouver le même problème, l’explication la plus proche pour le faire fonctionner est la même que celle fournie par @jfs ci-dessus.

ce qui a fonctionné pour moi, c'est les deux

  • en ajoutant /bin/bash au début de la commande ou du fichier que vous êtes
    faire face au problème avec, ou
  • en ajoutant Shebang #!/bin/sh en première ligne.

par ex.

#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