Is this the right way to run a shell script inside

2020-03-08 07:10发布

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.

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条回答
太酷不给撩
2楼-- · 2020-03-08 07:39

OSError: [Errno 8] Exec format error

This is an error reported by the operating system when trying to run /home/myuser/go.sh.

It looks to me like the shebang (#!) line of go.sh is not valid.

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

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

Removing the \ from the first line fixes the problem.

查看更多
ゆ 、 Hurt°
3楼-- · 2020-03-08 07:39

Change the code to following:

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

Notice "shell=True"

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

查看更多
爷的心禁止访问
4楼-- · 2020-03-08 07:40

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

查看更多
Deceive 欺骗
5楼-- · 2020-03-08 07:41

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.

查看更多
走好不送
6楼-- · 2020-03-08 07:45

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.

查看更多
一夜七次
7楼-- · 2020-03-08 07:45
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

查看更多
登录 后发表回答