проверка остановки процесса под оболочкой - PullRequest
0 голосов
/ 01 февраля 2012

Это часть программы на Python под Windows. Я пытаюсь сделать следующее: из HTML, я хочу создать PDF, а затем открыть его:

    #create the pdf
    os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name))
    #open the current pdf
    os.system("start %s%s" %(output_directory, pdf_document_name))

Проблема в том, что иногда сценарий создания pdf медленнее, поэтому я получаю сообщение об ошибке от терминала, что файла с таким именем не существует.
Я хочу спросить, можно ли назвать PDF открытым только тогда, когда создание успешно завершено. Я знаю, как это сделать, вызвав time.sleep (), но я думаю, что это не слишком профессионально.
Большое спасибо,
D

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

Независимо от метода, который вы используете для выполнения команд оболочки (подпроцесс, os.system и т. Д.), Вы должны убедиться, что ваш файл существует, прежде чем пытаться его открыть. Затем вы можете ввести задержку в цикл File-Exists-Else-Wait-Repeat, прежде чем пытаться ее открыть. Вы можете сделать это используя os.path.exists () :

#create the pdf
os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name))

#loop until pdf exists, but add some timer to avoid endless repetition
maxiterations = 60
exists = False
for i in range(maxiterations):
    if os.path.exists(os.path.join(output_directory, pdf_document_name)):
        exists = True
        break;
    time.sleep(1)
#open the current pdf
if exists:
    os.system("start %s%s" %(output_directory, pdf_document_name))
else:
    print 'Could not find file %s to open' % os.path.join(output_directory, pdf_document_name)

Еще одна вещь, на которую следует обратить внимание, это то, что она представляет уязвимость безопасности, поскольку файл может измениться за время, прошедшее между его проверкой и открытием (например, он мог быть заменен вредоносным кодом). Другой способ справиться с этим - попытаться открыть его в блоке try ... кроме ..., но это не решает проблему безопасности (файл мог быть заменен между созданием и вашей попыткой открыть его в любом случае) .

1 голос
/ 01 февраля 2012

Я не думаю, что в использовании time.sleep() есть что-то "непрофессиональное". На самом деле, наименее профессиональным (или, по крайней мере, Pythonic) в решении, которое вы предлагаете, является использование os.system. Вместо этого используйте функцию из модуля subprocess. В этом случае вы можете использовать subprocess.call, который ожидает выхода из программы, прежде чем продолжить. Так, например, если вы делаете это в интерактивном переводчике:

import subprocess, shlex
subprocess.call(shlex.split('sleep 5'))

Вы увидите, что Python ждет пять секунд, пока sleep завершит свою работу, прежде чем продолжить. (Затем он возвращает код завершения.) Shlex просто разбивает командную строку на список аргументов для использования call или несколькими другими функциями и классами, предоставленными subprocess.

>>> shlex.split("start wkhtmltopdf.exe result.html %s%s" %('out_dir/', 'pdf_name'))
['start', 'wkhtmltopdf.exe', 'result.html', 'out_dir/pdf_name']
...