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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4834483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:40:42  来源:igfitidea点击:

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

pythonlinuxbashshellunix

提问by TIMEX

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

回答by Adam Rosenfield

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. 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.

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

回答by ThiefMaster

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.

由于您通过数组传递所有参数(它将在内部用于 exec() 样式的调用)而不是作为由 shell 评估的参数字符串,因此它也非常安全,因为注入 shell 命令是不可能的。

回答by Johnsyweb

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.shis not valid.

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

Here's a sample script that runs from the shell but not from Popen:

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

#\!/bin/sh
echo "You've just called 
retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"], shell=True,)
$@."

Removing the \from the first line fixes the problem.

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

回答by jbp

Change the code to following:

将代码更改为以下内容:

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

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. This means that the string must be formatted exactly as it would be when typed at the shell prompt.

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

回答by George

I just got this error on Mac OS, while trying to call a one-line script using 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.

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

It appears, while the shell has a default executor for text files marked executable, subprocess.Popendoes not.

看起来,虽然外壳具有标记为可执行的文本文件的默认执行程序,subprocess.Popen但没有。

回答by unutbu

I recently ran into this problem with a script that looked like this:

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

OSError: [Errno 8] Exec format error

The script ran fine from the command line, but failed with

该脚本从命令行运行良好,但失败了

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

when executed via

通过执行时

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

(The solution, of course, was to remove the empty line).

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

回答by u6089746

##代码##

call just invoke Popen,use wait() method wait the popenargs completes

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