python to wait for shell command to complete

纵然是瞬间 提交于 2019-12-04 10:27:53

This is evil:

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

Instead,

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.

By passing an exact array rather than a string to Popen and not using shell=True, a filename with a space in it can't be interpreted as a more than one arguments, or a subshell command, or some other potentially malicious thing (think of a file with $(rm -rf ..) in its name).

Then, after calling p.wait() (there's no need for p.communicate() when you aren't capturing stderr or stdout), you must check p.returncode to determine whether the process was successful, and only proceed on to delete files if p.returncode == 0 (indicating success).

Your initial diagnosis, that p.communicate() is returning while the unrar process is still running, is not feasible; p.communicate() and p.wait() do not work that way.


If running across ssh, this changes a bit:

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]])

Is your problem waiting on the subprocess, or doing the things in order (meaning unpacking, then deleting).

If your problem is waiting on the subprocess, then you should check out the function subprocess.call

Check:

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

That function blocks until the other process terminates.

If your problem however is unpacking the files, and you don't necesarrily have to use subprocessess, then just check out any other lib for unpacking, like pyunrar2:

or this other one:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!