OSError:[Errno 8] Exec格式错误

时间:2014-12-22 16:34:18

标签: python subprocess

我很难解析subprocess.Popen的参数。我正在尝试在我的Unix服务器上执行脚本。在shell提示符下运行时的脚本语法如下: /usr/local/bin/script hostname = <hostname> -p LONGLIST。无论我如何尝试,脚本都不在subprocess.Popen

中运行

&#34; =&#34;之前和之后的空间是强制性的。

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

5 个答案:

答案 0 :(得分:77)

如果shell脚本顶部没有shebang行并且您正在尝试直接执行脚本,则可能会发生{p> 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

要修复它,只需添加shebang,例如,如果它是shell脚本;将#!/bin/sh放在脚本顶部:

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

执行exit 0时没有任何错误。


在POSIX系统上,shell会解析命令行,即您的脚本不会看到=周围的空格,例如,如果script是:

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

然后在shell中运行它:

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

产生

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

注意:'='周围没有空格。我在<hostname>周围添加了引号以转义重定向元字符<>

要在Python中模拟shell命令,请运行:

from subprocess import check_call

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

注意:没有shell=True。而且你不需要逃避<>因为没有运行shell。

"Exec format error"可能表示您的script格式无效,请执行:

$ file /usr/local/bin/script

找出它是什么。将架构与输出:

进行比较
$ uname -m

答案 1 :(得分:1)

你试过这个吗?

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

的评论编辑

答案 2 :(得分:1)

如果您认为&#34; =&#34;之前和之后的空间是强制性的,请将其作为列表中的单独项目。

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

答案 3 :(得分:1)

我将劫持此线程,指出当Popen的目标不可执行时,也可能发生此错误。当我意外地用zip文件覆盖一个完全可执行的二进制文件时,学到了很多东西。

答案 4 :(得分:0)

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