OSError: [Errno 8] Ошибка формата Exec
Мне сложно разобрать аргументы для subprocess.Popen. Я пытаюсь выполнить script на моем сервере Unix. Синтаксис script при запуске в командной строке выглядит следующим образом:
/usr/local/bin/script hostname = <hostname> -p LONGLIST
. Независимо от того, как я пытаюсь, script не работает внутри subprocess.Popen
Пространство до и после "=" является обязательным.
import subprocess
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname = ', 'actual server name', '-p', 'LONGLIST'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Вышеуказанное не работает.
И когда я использую shell = False, я получаю OSError: [Errno 8] Exec format error
Ответы
Ответ 1
OSError: [Errno 8] Exec format error
может произойти, если нет строки shebang в верхней части оболочки script, и вы пытаетесь выполнить script напрямую. Вот пример, который воспроизводит проблему:
>>> 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
Чтобы исправить это, просто добавьте shebang, например, если это оболочка script; prepend #!/bin/sh
в верхней части вашего script:
>>> with open('a','w') as f: f.write('#!/bin/sh\nexit 0')
...
>>> os.execl('./a', './a')
Он выполняет exit 0
без каких-либо ошибок.
В системах POSIX оболочка анализирует командную строку, т.е. ваш script не будет видеть пробелы вокруг =
, например, если script
:
#!/usr/bin/env python
import sys
print(sys.argv)
затем запустите его в оболочке:
$ /usr/local/bin/script hostname = '<hostname>' -p LONGLIST
дает:
['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
Примечание: нет пробелов вокруг '='
. Я добавил цитаты вокруг <hostname>
, чтобы избежать метасимволов перенаправления <>
.
Чтобы эмулировать команду оболочки в Python, запустите:
from subprocess import check_call
cmd = ['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
check_call(cmd)
Примечание: нет shell=True
. И вам не нужно бежать <>
, потому что никакая оболочка не запускается.
"Exec format error"
может указывать на то, что ваш script
имеет недопустимый формат, запустите:
$ file /usr/local/bin/script
чтобы узнать, что это такое. Сравните архитектуру с выходом:
$ uname -m
Ответ 2
Вы пробовали это?
Out = subprocess.Popen('/usr/local/bin/script hostname = actual_server_name -p LONGLIST'.split(), shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Отредактировано за каждый комментарий от @J.F.Sebastian
Ответ 3
Если вы считаете, что пространство до и после "=" является обязательным, попробуйте его как отдельный элемент в списке.
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname', '=', 'actual server name', '-p', 'LONGLIST'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Ответ 4
Я захвачу этот поток, чтобы указать, что эта ошибка также может произойти, если цель Popen не является исполняемой. Узнал это трудно, когда случайно я переопределил вполне исполняемый двоичный файл с zip файлом.
Ответ 5
Не было бы ошибкой упоминать, что Pexpect
вызывает подобную ошибку
#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
Здесь файл openssl_1.1.0f
по указанному пути содержит команду exec
указанную в нем, и при запуске запускает фактический двоичный файл openssl.
Обычно я не упоминал об этом, если у меня не было основной причины, но этой проблемы раньше не было. Невозможно найти подобную проблему, самое близкое объяснение, чтобы заставить ее работать, такое же, как и приведенное выше @jfs.
что для меня работало
- добавление
/bin/bash
в начале команды или файла, который вы
столкнувшись с проблемой, или - добавив shebang
#!/bin/sh
в качестве первой строки.
напр.
#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