it-roy-ru.com

Это правильный способ запуска сценария оболочки внутри Python?

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

Когда я выполню эти 2 строки, я буду делать именно это ?:

/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
30
TIMEX

Ошибка OSE: [Errno 8] Ошибка формата Exec

Это ошибка, сообщаемая операционной системой при попытке запустить /home/myuser/go.sh.

Мне кажется, что строка Шебанга (#!) go.sh недопустима. 

Вот пример сценария, который запускается из командной консоли, но не из Popen:

#\!/bin/sh
echo "You've just called $0 [email protected]"

Удаление \ из первой строки решает проблему.

33
Johnsyweb

Измените код на следующий:

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 - строка, она определяет команду строка для выполнения через Shell . Это означает, что строка должна быть отформатирован так, как это было бы, когда набирается в командной строке.

10
jbp

Недавно я столкнулся с этой проблемой со скриптом, который выглядел так:

% 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
unutbu
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

1
张小诚

Да, это прекрасно, если все, что вы делаете, это вызываете скрипт Shell, ожидаете его завершения и собираете его состояние выхода, позволяя наследовать его stdin, stdout и stderr от вашего процесса Python. Если вам нужен больший контроль над любым из этих факторов, тогда вы просто используете более общий subprocess.Popen , но в остальном все в порядке.

1
Adam Rosenfield

Я только что получил эту ошибку в Mac OS, пытаясь вызвать однострочный скрипт с использованием subprocess.call. Сценарий работает нормально при вызове из командной строки. После добавления строки Shebang #!/usr/bin/env sh она также работала нормально через subprocess.call.

Похоже, что в командной консоли по умолчанию есть исполнитель для текстовых файлов, помеченных как исполняемые, а subprocess.Popen - нет.

1
George

Да, это предпочтительный способ выполнить что-то ..

Поскольку вы передаете все аргументы через массив (который будет использоваться для внутреннего вызова в стиле exec ()), а не как строка аргумента, вычисляемая оболочкой, это также очень безопасно, поскольку внедрение команд оболочки невозможно.

0
ThiefMaster