Команда Python popen. Подождите, пока команда не будет завершена

У меня есть сценарий, в котором я запускаю команду popen a shell. Проблема в том, что сценарий не дожидается завершения выполнения этой команды popen и сразу же продолжает работу.

om_points = os.popen(command, "w")
.....

Как я могу сказать своему скрипту Python дождаться завершения команды оболочки?


person michele    schedule 14.05.2010    source источник


Ответы (7)


В зависимости от того, как вы хотите работать со своим скриптом, у вас есть два варианта. Если вы хотите, чтобы команды блокировались и ничего не делали во время выполнения, вы можете просто использовать subprocess.call.

#start and block until done
subprocess.call([data["om_points"], ">", diz['d']+"/points.xml"])

Если вы хотите что-то делать во время выполнения или загружать данные в stdin, вы можете использовать communicate после вызова popen.

#start and process things, then wait
p = subprocess.Popen([data["om_points"], ">", diz['d']+"/points.xml"])
print "Happens while running"
p.communicate() #now wait plus that you can send commands to process

Как указано в документации, wait может заблокироваться, поэтому рекомендуется общаться.

person unholysampler    schedule 14.05.2010
comment
Ознакомьтесь с документами на subprocess.call - person thornomad; 15.05.2010
comment
Хотя во многих ответах предпочтение отдается подпроцессу, он не может очень хорошо обрабатывать пространство и квоту в команде. Приведенный выше ответ не решает напрямую открытый вопрос os.popen. - person Chang; 20.07.2019
comment
подпроцесс может быть до 2 раз медленнее, чем система ОС - bugs.python.org/issue37790 - person MonsieurBeilto; 08.03.2020
comment
subprocess.run() был добавлен в Python 3.5 и является рекомендуемым подходом к вызову подпроцессов. - person LoMaPh; 23.09.2020

Вы можете использовать subprocess для этого.

import subprocess

#This command could have multiple commands separated by a new line \n
some_command = "export PATH=$PATH://server.sample.mo/app/bin \n customupload abc.txt"

p = subprocess.Popen(some_command, stdout=subprocess.PIPE, shell=True)

(output, err) = p.communicate()  

#This makes the wait possible
p_status = p.wait()

#This will give you the output of the command being executed
print "Command output: " + output
person Touchstone    schedule 15.08.2016
comment
подпроцесс может быть до 2 раз медленнее, чем система ОС - bugs.python.org/issue37790 - person MonsieurBeilto; 08.03.2020

Заставьте popen не продолжать, пока весь вывод не будет прочитан, выполнив:

os.popen(command).read()
person Alberto    schedule 20.11.2019
comment
Я не эксперт по питону, но это, кажется, самое простое решение, которое вносит наименьшее количество изменений в исходный код. Есть ли причина, по которой это не было бы хорошим решением? - person jdmcnair; 21.02.2020
comment
это сработало для меня - person Ermolai; 18.06.2021

Пусть команда, которую вы пытаетесь передать, будет

os.system('x')

затем вы превращаете это в заявление

t = os.system('x')

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

person Chidhambararajan NRM    schedule 13.04.2018

Вам нужен метод wait.

person Olivier Verdier    schedule 14.05.2010
comment
Но если я наберу: om_points = os.popen (data [om_points] + ›+ diz ['d'] + / points.xml, w) .wait (), я получаю эту ошибку: Traceback (последний вызов последний): File ./model_job.py, строка 77, в ‹module› om_points = os.popen (data [om_points] + ›+ diz ['d'] + / points.xml, w) .wait () AttributeError: объект 'file' не имеет атрибута "ждать". В чем проблема? Еще раз спасибо. - person michele; 15.05.2010
comment
Вы не переходили по предоставленной мной ссылке. wait - это метод класса subprocess. - person Olivier Verdier; 16.05.2010
comment
ожидание может зайти в тупик, если процесс записывает в стандартный вывод и никто его не читает - person ansgri; 19.12.2016
comment
подпроцесс может быть до 2 раз медленнее, чем система ОС - bugs.python.org/issue37790 - person MonsieurBeilto; 08.03.2020

wait () у меня отлично работает. Подпроцессы p1, p2 и p3 выполняются одновременно. Таким образом, все процессы выполняются через 3 секунды.

import subprocess

processes = []

p1 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
p2 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
p3 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)

processes.append(p1)
processes.append(p2)
processes.append(p3)

for p in processes:
    if p.wait() != 0:
        print("There was an error")

print("all processed finished")
person simibac    schedule 15.11.2018
comment
подпроцесс может быть до 2 раз медленнее, чем система ОС - bugs.python.org/issue37790 - person MonsieurBeilto; 08.03.2020

Я думаю, что process.communicate () подойдет для вывода небольшого размера. Для большей производительности это не лучший подход.

person Barsha Lamichhane    schedule 04.11.2020