这是在Python中运行shell脚本的正确方法吗?

时间:2011-01-29 01:20:28

标签: python linux bash shell unix

import subprocess
retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"])

当我运行这两行时,我会这样做吗?:

/home/myuser/go.sh abc.txt xyz.txt

为什么会出现此错误?但是当我正常运行go.sh时,我没有得到那个错误。

File "/usr/lib/python2.6/subprocess.py", line 480, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
    raise child_exception
OSError: [Errno 8] Exec format error

7 个答案:

答案 0 :(得分:33)

  

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

这是操作系统在尝试运行/home/myuser/go.sh时报告的错误。

在我看来,#!的shebang(go.sh)行无效。

这是一个从shell运行但不是从Popen运行的示例脚本:

#\!/bin/sh
echo "You've just called $0 $@."

从第一行删除\可解决问题。

答案 1 :(得分:10)

将代码更改为以下内容:

retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"], shell=True,)

注意“shell = True”

来自:http://docs.python.org/library/subprocess.html#module-subprocess

  

在Unix上,shell = True:如果args是a   string,它指定命令   要通过shell执行的字符串。   这意味着字符串必须是   格式完全如同   在shell提示符下键入。

答案 2 :(得分:3)

我最近遇到了一个看起来像这样的脚本的问题:

% cat /tmp/test.sh
                              <-- Note the empty line
#!/bin/sh
mkdir /tmp/example

脚本从命令行运行正常,但是

失败了
OSError: [Errno 8] Exec format error

通过

执行时
subprocess.Popen(['/tmp/test.sh']).communicate()

(解决方案当然是删除空行)。

答案 3 :(得分:1)

是的,如果你所做的只是调用shell脚本,等待它完成,并收集它的退出状态,同时让它的stdin,stdout和stderr从你的Python进程继承,那就完全没问题了。如果您需要对这些因素中的任何一个进行更多控制,那么您只需使用更通用的subprocess.Popen,否则您所拥有的就可以了。

答案 4 :(得分:1)

我在Mac OS上遇到此错误,同时尝试使用subprocess.call调用单行脚本。从命令行调用时脚本运行正常。添加shebang行#!/usr/bin/env sh后,它也可以通过subprocess.call运行。

看来,虽然shell有一个标记为可执行文件的默认执行程序,subprocess.Popen却没有。

答案 5 :(得分:1)

In :call??
Signature: call(*popenargs, **kwargs)
Source:   
def call(*popenargs, **kwargs):
    """Run command with arguments.  Wait for command to complete, then
    return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    return Popen(*popenargs, **kwargs).wait()
File:      /usr/lib64/python2.7/subprocess.py
Type:      function

调用只是调用Popen,使用wait()方法等待popenargs完成

答案 6 :(得分:0)

是的,这是执行某些操作的首选方式..

由于您通过数组传递所有参数(将在内部使用gor an exec() - 样式调用)而不是作为shell评估的参数字符串,所以它也非常安全,因为无法注入shell命令。 / p>