[英]OSError: [Errno 8] Exec format error
I am having hard time parsing the arguments to subprocess.Popen.我很难解析 subprocess.Popen 的参数。 I am trying to execute a script on my Unix server.
我正在尝试在我的 Unix 服务器上执行脚本。 The script syntax when running on shell prompt is as follows:
/usr/local/bin/script hostname = <hostname> -p LONGLIST
.在 shell 提示符下运行时的脚本语法如下:
/usr/local/bin/script hostname = <hostname> -p LONGLIST
。 No matter how I try, the script is not running inside subprocess.Popen无论我如何尝试,脚本都没有在 subprocess.Popen 中运行
The space before and after "=" is mandatory. “=”前后的空格是必须的。
import subprocess
Out = subprocess.Popen(['/usr/local/bin/script', 'hostname = ', 'actual server name', '-p', 'LONGLIST'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
The above does not work.以上不起作用。
And when I use shell=False, I get OSError: [Errno 8] Exec format error
当我使用 shell=False 时,我得到
OSError: [Errno 8] Exec format error
OSError: [Errno 8] Exec format error
can happen if there is no shebang line at the top of the shell script and you are trying to execute the script directly. OSError: [Errno 8] Exec format error
。 Here's an example that reproduces the issue:这是重现该问题的示例:
>>> 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
To fix it, just add the shebang eg, if it is a shell script;要修复它,只需添加 shebang,例如,如果它是一个 shell 脚本; prepend
#!/bin/sh
at the top of your script:在脚本顶部添加
#!/bin/sh
:
>>> with open('a','w') as f: f.write('#!/bin/sh\nexit 0')
...
>>> os.execl('./a', './a')
It executes exit 0
without any errors.它执行
exit 0
没有任何错误。
On POSIX systems, shell parses the command line ie, your script won't see spaces around =
eg, if script
is:在 POSIX 系统上,shell 解析命令行,即,您的脚本不会在
=
周围看到空格,例如,如果script
是:
#!/usr/bin/env python
import sys
print(sys.argv)
then running it in the shell:然后在shell中运行它:
$ /usr/local/bin/script hostname = '<hostname>' -p LONGLIST
produces:产生:
['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
Note: no spaces around '='
.注意:
'='
周围没有空格。 I've added quotes around <hostname>
to escape the redirection metacharacters <>
.我在
<hostname>
周围添加了引号以转义重定向元字符<>
。
To emulate the shell command in Python, run:要在 Python 中模拟 shell 命令,请运行:
from subprocess import check_call
cmd = ['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
check_call(cmd)
Note: no shell=True
.注意:没有
shell=True
。 And you don't need to escape <>
because no shell is run.而且您不需要转义
<>
因为没有运行任何 shell。
"Exec format error"
might indicate that your script
has invalid format, run: "Exec format error"
可能表明您的script
格式无效,请运行:
$ file /usr/local/bin/script
to find out what it is.找出它是什么。 Compare the architecture with the output of:
将架构与以下输出进行比较:
$ uname -m
I will hijack this thread to point out that this error may also happen when target of Popen is not executable.我将劫持该线程以指出当 Popen 的目标不可执行时也可能发生此错误。 Learnt it hard way when by accident I have had override a perfectly executable binary file with zip file.
当我偶然用 zip 文件覆盖了一个完全可执行的二进制文件时,我学到了很多东西。
Have you tried this?你试过这个吗?
Out = subprocess.Popen('/usr/local/bin/script hostname = actual_server_name -p LONGLIST'.split(), shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
Edited per the apt comment from @JFSebastian根据@JFSebastian 的恰当评论进行编辑
It wouldn't be wrong to mention that Pexpect
does throw a similar error提到
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
Over here, the openssl_1.1.0f
file at the specified path has exec
command specified in it and is running the actual openssl binary when called.在这里,指定路径的
openssl_1.1.0f
文件中指定了exec
命令,并在调用时运行实际的 openssl 二进制文件。
Usually, I wouldn't mention this unless I have the root cause, but this problem was not there earlier.通常,除非我有根本原因,否则我不会提及这一点,但这个问题更早不存在。 Unable to find the similar problem, the closest explanation to make it work is the same as the one provided by @jfs above.
找不到类似的问题,使其工作的最接近的解释与上面@jfs提供的解释相同。
what worked for me is both对我有用的是
/bin/bash
at the beginning of the command or file you are/bin/bash
#!/bin/sh
as the first line.#!/bin/sh
作为第一行。 for ex.例如。
#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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.