OSError: [Errno 8] 执行格式错误

Posted

技术标签:

【中文标题】OSError: [Errno 8] 执行格式错误【英文标题】:OSError: [Errno 8] Exec format error 【发布时间】:2015-02-20 18:52:18 【问题描述】:

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

【问题讨论】:

大胆猜测:试试'hostname = actual server name' 而不是'hostname = ', 'actual server name' 根据你在提示符下运行它的方式,看起来hostname 是一个参数,= 是一个单独的参数,这很奇怪。你确定=周围有空格吗? 嗨布莱恩,是的,必须有空间。脚本接受 key=value 类型参数。 @user3477108 - 这很令人费解,你说必须有一个空格,然后给出一个没有空格的“key=value”示例。当然,由于您的命令行示例有一个空格,我们知道 key = value 应该是 Popen 的 3 个参数,如 insti 所示。 谢谢。我在原始脚本周围写了一个小包装脚本,以忽略“=”周围的空间包装脚本运行良好。 【参考方案1】:

OSError: [Errno 8] Exec format error 可能发生在 shell 脚本顶部没有 shebang 行并且您尝试直接执行脚本的情况下。这是一个重现该问题的示例:

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

注意:'=' 周围没有空格。我在&lt;hostname&gt; 周围添加了引号来转义重定向元字符&lt;&gt;

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

from subprocess import check_call

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

注意:没有shell=True。而且您不需要转义 &lt;&gt;,因为没有运行任何 shell。

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

$ file /usr/local/bin/script

找出它是什么。将架构与以下输出进行比较:

$ uname -m

【讨论】:

我一定是不小心删除了我在 vim 中的部分 shebang ......直到你的帖子我才迷路。谢谢。 @nbro:错了。看看我回答中的第一个代码示例。如果没有 shebang,你会得到 OSError。这与your question 中的错误相同。如果您在 shell 中运行命令,则不会出现错误(在这种情况下,没有 shebang 意味着:“作为 shell 脚本运行”)。 subprocess.check_output() 默认情况下不运行 shell - 没有子进程函数运行 shell,除非你明确询问(如果你不知道;要求重新打开你的问题)。 这对我有帮助:#!/usr/bin/env python @skygeek:这种 shebang 只适用于 Python 脚本。 对我来说就是缺少 shebang 行!【参考方案2】:

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

【讨论】:

这就是为什么我的回答建议使用file your-executable 命令(它会显示您有一个 zip 存档)。尽管某些 zip 存档也可能是正确的可执行文件,例如 python: can executable zip files include data files?【参考方案3】:

你试过了吗?

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 的恰当评论编辑

【讨论】:

您好,Rchang,感谢您的反馈。这是行不通的。我的脚本在“=”前后需要空格。你的解决方案能提供吗? 这在这个命令上应该可以正常工作,但不是一个好的通用解决方案,因为它不允许您转义嵌入的空格。 shlex.split 方法可能是更好的选择。 do not use shell=True and a list argument together @J.F.Sebastian 是的,你当然是对的 - 谢谢你的收获。【参考方案4】:

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

【讨论】:

【参考方案5】:

如果您认为“=”前后的空格是强制性的,请尝试将其作为列表中的单独项目。

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

【讨论】:

投反对票。 Do not use shell=True and a list argument(在大多数情况下是一个错误)。

以上是关于OSError: [Errno 8] 执行格式错误的主要内容,如果未能解决你的问题,请参考以下文章

pyaudio-OSError: [Errno -9999] 意外主机错误

OSError:[Errno 26] 文本文件忙:'baremetrics'

OSError: [Errno 5] Raspberry PI GPS shield Python 上的输入/输出错误

python使用open的OSError: [Errno 22] Invalid argument错误

OSError : [Errno 24] 打开的文件太多

OSError - Errno 13 权限被拒绝