Это правильный способ запустить скрипт оболочки внутри Python? - PullRequest
30 голосов
/ 29 января 2011
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

Ответы [ 7 ]

33 голосов
/ 29 января 2011

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

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

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

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

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

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

10 голосов
/ 16 февраля 2011

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

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

3 голосов
/ 22 октября 2012

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

% 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()

(Решение, конечно, заключалось в удалении пустой строки).

1 голос
/ 16 октября 2017
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 голос
/ 16 апреля 2011

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

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

1 голос
/ 29 января 2011

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

0 голосов
/ 29 января 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...