Какая разница между подпроцессом Popen и вызовом (как я могу их использовать)? - программирование

Какая разница между подпроцессом Popen и вызовом (как я могу их использовать)?

Я хочу вызвать внешнюю программу из Python. Для этого я использовал Popen() и call().

Какая разница между двумя?

Моя конкретная цель - запустить следующую команду из Python. Я не уверен, как работают перенаправления.

./my_script.sh > output

Я читаю документацию, и он говорит, что call() - это функция удобства или функция быстрого доступа. Мы теряем всякую власть, используя call() вместо Popen()?

4b9b3361

Ответ 1

Есть два способа сделать переадресацию. Оба применяются к subprocess.Popen или subprocess.call.

  • Задайте аргумент ключевого слова shell = True или executable = /path/to/the/shell и укажите команду так же, как вы ее там.

  • Поскольку вы просто перенаправляете вывод в файл, задайте аргумент ключевого слова

    stdout = an_open_writeable_file_object
    

    где объект указывает на файл output.

subprocess.Popen более общий, чем subprocess.call.

Popen не блокируется, что позволяет вам взаимодействовать с процессом во время его работы или продолжать с другими вещами в вашей программе Python. Вызов Popen возвращает объект Popen.

call блокирует. Хотя он поддерживает все те же аргументы, что и конструктор Popen, поэтому вы все равно можете установить выходные данные процесса, переменные среды и т.д., Ваш script ждет завершения программы, а call возвращает код, представляющий статус процесса.

returncode = call(*args, **kwargs) 

в основном совпадает с вызовом

returncode = Popen(*args, **kwargs).wait()

call - это просто удобная функция. Реализация в CPython находится в subprocess.py:

def call(*popenargs, timeout=None, **kwargs):
    """Run command with arguments.  Wait for command to complete or
    timeout, then return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    with Popen(*popenargs, **kwargs) as p:
        try:
            return p.wait(timeout=timeout)
        except:
            p.kill()
            p.wait()
            raise

Как вы можете видеть, это тонкая обертка вокруг Popen.