OSError:[Errno 8] Exec格式错误

use*_*108 36 python subprocess

我很难解析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)
Run Code Online (Sandbox Code Playgroud)

以上不起作用.

当我使用shell = False时,我得到了 OSError: [Errno 8] Exec format error

jfs*_*jfs 89

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
Run Code Online (Sandbox Code Playgroud)

要修复它,只需添加shebang,例如,如果它是一个shell脚本; 前置#!/bin/sh在脚本的顶部:

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

它执行exit 0没有任何错误.


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

#!/usr/bin/env python
import sys
print(sys.argv)
Run Code Online (Sandbox Code Playgroud)

然后在shell中运行它:

$ /usr/local/bin/script hostname = '<hostname>' -p LONGLIST
Run Code Online (Sandbox Code Playgroud)

生产:

['/usr/local/bin/script', 'hostname', '=', '<hostname>', '-p', 'LONGLIST']
Run Code Online (Sandbox Code Playgroud)

注意:周围没有空格'='.我添加了引号<hostname>以逃避重定向元字符<>.

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

from subprocess import check_call

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

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

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

$ file /usr/local/bin/script
Run Code Online (Sandbox Code Playgroud)

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

$ uname -m
Run Code Online (Sandbox Code Playgroud)


Dra*_*els 5

我将劫持该线程以指出,当Popen目标不可执行时,也可能发生此错误。当我偶然用zip文件覆盖了一个完全可执行的二进制文件时,很难用它来学习。


rch*_*ang 2

你试过这个吗?

Out = subprocess.Popen('/usr/local/bin/script hostname = actual_server_name -p LONGLIST'.split(), shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
Run Code Online (Sandbox Code Playgroud)

根据@JFSebastian 的恰当评论进行编辑