5

我正在运行脚本来解压缩一些文件,然后删除 rar 文件。我通过shell运行命令来做到这一点。我已经尝试了几种不同的方法让脚本等到它完成解压缩文件,但它仍然继续并在文件完成使用之前删除文件。

我已经尝试了下面的代码,这是不行的。我试图看看我是否可以让 wait() 工作,但也没有运气。

有任何想法吗?运行 python 2.7

编辑:我希望脚本运行命令:)

            p = subprocess.Popen('unrar e ' + root + '/' + i + ' ' + testfolder,
                                 bufsize=2048, shell=True,
                                 stdin=subprocess.PIPE)
            p.stdin.write('e')
            p.communicate()

for root, dirs, files in os.walk(testfolder):
    for i in files:

        print 'Deleting rar files'
        os.remove(i)

for i in os.listdir(testfolder):
    if os.path.isdir(testfolder + i):
        shutil.rmtree(testfolder + i)
4

2 回答 2

6

这是邪恶的:

p = subprocess.Popen('unrar e ' + root + '/' + i + ' ' + testfolder,
        bufsize=2048, shell=True, stdin=subprocess.PIPE)

反而,

p = subprocess.Popen(['unrar', 'e', '%s/%s' % (root, i), testfolder],
        bufsize=2048, stdin=subprocess.PIPE)
p.stdin.write('e')
p.wait()
if p.returncode == 0:
    pass # put code that must only run if successful here.

通过将一个精确的数组而不是一个字符串传递给Popen并且不使用shell=True,一个带有空格的文件名不能被解释为一个以上的参数,或者一个子shell命令,或者其他一些潜在的恶意东西(想想一个文件$(rm -rf ..)以其名义)。

然后,在调用之后p.wait()p.communicate()没有捕获stderr或stdout时不需要),您必须检查以确定该过程是否成功,并且只有在(表示成功)p.returncode时才继续删除文件。p.returncode == 0

您的初始诊断(即p.communicate()unrar进程仍在运行时返回)是不可行的;p.communicate()不要那样p.wait()工作。


如果跨越ssh,这会发生一些变化:

import pipes # in Python 2.x; in 3.x, use shlex.quote() instead
p = subprocess.Popen(['ssh', ' '.join(
      [pipes.quote(s) for s in ['unrar', 'e', '%s/%s' % (root, i), testfolder]])
于 2013-04-24T16:13:43.603 回答
1

你的问题是在等待子进程,还是按顺序做事(意味着解包,然后删除)。

如果您的问题正在等待子进程,那么您应该检查该功能subprocess.call

查看:

http://docs.python.org/2/library/subprocess.html#module-subprocess

该函数会阻塞,直到另一个进程终止。

但是,如果您的问题是解压缩文件,并且您不必使用子进程,那么只需检查任何其他库进行解压缩,例如 pyunrar2:

或另一个:

于 2013-04-24T16:07:05.827 回答