1

所以我开始接触 Python,我正在编写一个脚本来:

  1. 使用 urllib.urlretrieve 下载 RPM。
  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'命令正在打开一些东西,只要脚本运行就像我需要明确关闭的东西......?这有任何意义吗?:)

谢谢!Ĵ

4

1 回答 1

0

subprocess.Popen是非阻塞的,所以你基本上有一个竞争条件 - 在你的调用之间Popen并且不能保证这些进程可以在运行rmtree之前完成(甚至开始!) 。rmtree

我建议你等待 Popen 对象返回

cpio.wait()
rpm2cpio.wait()

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

subprocess.call对于您如何通过管道传输命令,使用阻塞看起来不像是一个选项。

于 2017-11-01T16:36:45.923 回答