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

时间:2021-12-12 10:00:46
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

7 个解决方案

#1


33  

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.

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

#2


10  

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. 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提示符下键入时完全相同。

#3


3  

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

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

#4


1  

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,否则您所拥有的就可以了。

#5


1  

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 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却没有。

#6


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

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

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

#7


0  

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命令。

#1


33  

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.

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

#2


10  

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. 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提示符下键入时完全相同。

#3


3  

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

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

#4


1  

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,否则您所拥有的就可以了。

#5


1  

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 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却没有。

#6


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

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

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

#7


0  

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命令。