python等待shell命令完成
我正在运行脚本来取消一些文件,然后删除rar文件。 我通过shell运行命令来实现这一点。我尝试了几种不同的方法让脚本等待解包完成,但它仍然会在使用文件之前删除文件 我已经尝试了下面的代码,这是不可能的。我试着看看我是否能让等待开始工作,但也没有运气 有什么想法吗? 运行Python2.7 编辑:我希望脚本运行命令:)python等待shell命令完成,python,shell,subprocess,wait,Python,Shell,Subprocess,Wait,我正在运行脚本来取消一些文件,然后删除rar文件。 我通过shell运行命令来实现这一点。我尝试了几种不同的方法让脚本等待解包完成,但它仍然会在使用文件之前删除文件 我已经尝试了下面的代码,这是不可能的。我试着看看我是否能让等待开始工作,但也没有运气 有什么想法吗? 运行Python2.7 编辑:我希望脚本运行命令:) 您的问题是等待子流程,还是按顺序进行操作(意味着解包,然后删除) 如果您的问题正在等待子流程,那么您应该检查函数subprocess.call 检查: 该函数将一直阻塞,直到另
您的问题是等待子流程,还是按顺序进行操作(意味着解包,然后删除) 如果您的问题正在等待子流程,那么您应该检查函数
subprocess.call
检查:
该函数将一直阻塞,直到另一个进程终止
但是,如果您的问题是解包文件,并且您不必使用Subprocess,那么只需查看任何其他用于解包的库,如pyunrar2:
- 这是邪恶的:
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()
(不捕获stderr或stdout时不需要p.communicate()
)后,必须检查p.returncode
以确定该过程是否成功,并且只有在p.returncode==0
时才继续删除文件(表示成功)
您的初始诊断是,p.communicate()
在unar
进程仍在运行时返回,这是不可行的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]])
如果您等待该命令,则不需要
子进程
我希望让脚本运行该命令。os.system(“some command”)
正在阻止afaik。。。。所以它应该阻塞,直到UNAR至少返回(我假设是在它完成时)。。。虽然我认为subaccess.communicate也会阻塞。。。我的猜测是,UNRR不会等到它完成后才返回出口code@KarolyHorvath但是,使用subprocess.Popen
比使用os.system()
安全得多,因为它可以在没有外壳的情况下使用。(当然,这里不是这样使用的,但这是不好的做法和不安全的)。我的问题是我希望它先完成解包,然后删除文件。现在,它将在完成解包之前删除文件。然后只需使用子进程.call()
而不是子进程。Popen
@vlad-ardelan使用子进程。call()
与需要像原始代码一样将字符写入命令的stdin不兼容。您可能需要p.stdin.close()
在p.wait()
之前,否则如果程序等待EOF,代码将挂起等待子进程。此外,如果子进程是ssh
,我发现即使使用第二种形式,我仍然必须在参数周围加上引号,并加上空格,否则远程系统不会将其视为单个参数。@Michael,ssh除了正确使用此技术避免的本地扩展之外,还进行远程扩展。如果要为ssh准备命令,请使用pipes.quote()
(或者在Python 3.x中使用shlex.quote()
)来转义您的参数。@Michael,…我已经扩展了答案以直接解决该场景。
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]])