简体   繁体   English

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

[英]Is this the right way to run a shell script inside Python?

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

When I run these 2 lines, will I be doing exactly this?: 当我运行这两行时,我会这样做吗?:

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

Why do I get this error? 为什么我会收到此错误? But when I run go.sh normally, I don't get that error. 但是当我正常运行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

OSError: [Errno 8] Exec format error OSError:[Errno 8] Exec格式错误

This is an error reported by the operating system when trying to run /home/myuser/go.sh . 这是操作系统在尝试运行/home/myuser/go.sh时报告的错误。

It looks to me like the shebang ( #! ) line of go.sh is not valid. 它看起来像go.sh的shebang( #! )行无效。

Here's a sample script that runs from the shell but not from Popen : 这是一个从shell运行但不是从Popen运行的示例脚本:

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

Removing the \\ from the first line fixes the problem. 从第一行删除\\可以解决问题。

Change the code to following: 将代码更改为以下内容:

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

Notice "shell=True" 注意“shell = True”

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

On Unix, with shell=True: If args is a string, it specifies the command string to execute through the shell. 在Unix上,shell = True:如果args是一个字符串,它指定要通过shell执行的命令字符串。 This means that the string must be formatted exactly as it would be when typed at the shell prompt. 这意味着字符串的格式必须与在shell提示符下键入时完全相同。

I recently ran into this problem with a script that looked like this: 我最近用一个看起来像这样的脚本遇到了这个问题:

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

The script ran fine from the command line, but failed with 该脚本从命令行运行正常,但失败了

OSError: [Errno 8] Exec format error

when executed via 通过执行时

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

(The solution, of course, was to remove the empty line). (解决方案当然是删除空行)。

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

call just invoke Popen,use wait() method wait the popenargs completes 调用刚刚调用Popen,使用wait()方法等待popenargs完成

Yes, that's perfectly fine if all you're doing is calling the shell script, waiting for it to complete, and gathering its exit status, while letting its stdin, stdout, and stderr be inherited from your Python process. 是的,如果你所做的只是调用shell脚本,等待它完成,并收集它的退出状态,同时让它的stdin,stdout和stderr从你的Python进程继承,那就完全没问题了。 If you need more control over any of those factors, then you just use the more general subprocess.Popen , but otherwise what you have is fine. 如果您需要对这些因素中的任何一个进行更多控制,那么您只需使用更通用的subprocess.Popen ,否则您所拥有的就可以了。

I just got this error on Mac OS, while trying to call a one-line script using subprocess.call . 我在Mac OS上遇到此错误,同时尝试使用subprocess.call调用单行脚本。 The script ran fine when called from the command line. 从命令行调用时脚本运行正常。 After adding the shebang line #!/usr/bin/env sh , it also ran fine via subprocess.call . 添加shebang line #!/usr/bin/env sh ,它也通过subprocess.call运行良好。

It appears, while the shell has a default executor for text files marked executable, subprocess.Popen does not. 看来,虽然shell有一个标记为executable的文本文件的默认执行程序,但subprocess.Popen却没有。

Yes, this is the preferred way to execute something.. 是的,这是执行某些事情的首选方式..

Since you are passing all arguments through an array (which will be used gor an exec()-style call internally) and not as an argument string evaluated by a shell it's also very secure as injection of shell commands is impossible. 由于您通过一个数组传递所有参数(将在内部使用gor一个exec() - 样式调用)而不是作为shell评估的参数字符串,所以它也非常安全,因为无法注入shell命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM