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

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

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

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

./my_script.sh > output

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

1 ответ

Решение

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

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

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

    stdout = an_open_writeable_file_object
    

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

subprocess.Popen является более общим, чем subprocess.call,

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

call блокирует Хотя он поддерживает все те же аргументы, что и Popen конструктор, так что вы все еще можете установить выходные данные процесса, переменные окружения и т. д., ваш скрипт ожидает завершения программы, и 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,

Другой ответ очень полный, но вот практическое правило:

  • call блокирует:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
    
  • Popen неблокирующий:

    Popen('notepad.exe')
    print('hello')  # immediately executed
    
Другие вопросы по тегам