Подтвердить что ты не робот

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

4b9b3361

Ответ 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