Python - Почему я вижу этот вывод?

Итак, я вхожу в Python и пишу скрипт для:

  1. Загрузите RPM с помощью urllib.urlretrieve.
  2. Распакуйте файлы, используя rpm2cpio и cpio.
  3. Сделайте что-нибудь с файлами.
  4. Очистить с помощью shutil.rmtree.

Функционально все хорошо, он делает все это, но так как я вставил код очистки, я получаю следующий вывод:

rpm2cpio: MyRPM.rpm: No such file or directory
cpio: premature end of archive

Вот код:

#!/usr/bin/python

from contextlib import contextmanager
import os, subprocess, shutil

@contextmanager
def cd(directory):
    startingDirectory = os.getcwd()
    os.chdir(os.path.expanduser(directory))
    try:
        yield
    finally:
        os.chdir(startingDirectory)

# Extract the files from the RPM to the temp directory
with cd("/tempdir"):
    rpm2cpio = subprocess.Popen(["rpm2cpio", "MyRPM.rpm"], stdout=subprocess.PIPE)
    cpio = subprocess.Popen(["cpio", "-idm", "--quiet"], stdin=rpm2cpio.stdout, stdout=None)

# Do
# Some
# Things
# Involving
# Shenanigans

# Remove the temp directory and all it's contents
shutil.rmtree("/tempdir")

Если вы видите здесь какие-то синтаксические проблемы с кодом (или пропускаем импорт или что-то), пожалуйста, игнорируйте, если это не относится к причине, по которой я получаю два сообщения. Я пытался обрезать сценарий до нужных битов. Все, что я ищу, - это объяснение того, почему вышеперечисленные два сообщения печатаются. Я бы предположил, что скрипт выполняется сверху вниз, но теперь я думаю, что могу ошибаться в этом случае?

РЕДАКТИРОВАТЬ: Такое ощущение, что команды 'rpm2cpio' и 'cpio' оставляют что-то открытым, пока скрипт работает как то, что мне нужно явно закрыть...? Имеет ли это смысл?:)

Спасибо! J

1 ответ

Решение

subprocess.Popen не блокирует, поэтому у вас в основном есть состояние гонки - между вашими звонками Popen а также rmtree нет никаких гарантий, что эти процессы могут завершиться (или даже начать!) до rmtree пробеги.

Я предлагаю вам дождаться возвращения объектов Popen с

cpio.wait()
rpm2cpio.wait()

# Remove the temp directory and all it's contents
shutil.rmtree("/tempdir")

Использование блокировки subprocess.call не похоже на вариант с тем, как вы передаете команды.

Другие вопросы по тегам