Ошибка OSE: [Errno 8] Ошибка формата Exec
Мне трудно разобрать аргументы для подпроцесса. Открыть. Я пытаюсь выполнить скрипт на моем Unix-сервере. Синтаксис скрипта при запуске в командной строке выглядит следующим образом:/usr/local/bin/script hostname = <hostname> -p LONGLIST
, Независимо от того, как я пытаюсь, скрипт не работает внутри подпроцесса. Открыть
Пробел до и после "=" является обязательным.
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
4 ответа
OSError: [Errno 8] Exec format error
Это может произойти, если в верхней части сценария оболочки нет строки Шебанга, и вы пытаетесь выполнить сценарий напрямую. Вот пример, который воспроизводит проблему:
>>> 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
Чтобы это исправить, просто добавьте шебанг, например, если это скрипт оболочки; перед именем #!/bin/sh
в верхней части вашего сценария:
>>> with open('a','w') as f: f.write('#!/bin/sh\nexit 0')
...
>>> os.execl('./a', './a')
Выполняет exit 0
без каких-либо ошибок.
В системах POSIX оболочка анализирует командную строку, т. Е. Ваш скрипт не будет видеть пробелы вокруг =
например, если 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
Я перехватываю этот поток, чтобы указать, что эта ошибка также может произойти, когда цель Popen не исполняется. Трудно научился, когда случайно переопределил отлично исполняемый двоичный файл с zip-файлом.
Вы пробовали это?
Out = subprocess.Popen('/usr/local/bin/script hostname = actual_server_name -p LONGLIST'.split(), shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Отредактировано согласно меткому комментарию от @JFSebastian
Было бы неправильно упомянуть, что 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
в начале команды или файла вы
столкнувшись с проблемой, или - добавив шебанг
#!/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
Если вы считаете, что пробел до и после "=" является обязательным, попробуйте использовать его как отдельный элемент в списке.
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname', '=', 'actual server name', '-p', 'LONGLIST'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)