为什么subprocess.Popen阻塞?

Qui*_*ten 6 python subprocess

我有一个处理登录的python cgi脚本,这是因为我的网站是三个(学校)网站的组合,在我的网站可以使用之前,需要从这些网站中提取数据.这个提取需要2分钟,所以我想制作一个花哨的(半假的)加载屏幕.

我的注册码以:

import subprocess
token = "".join(random.choice(
                    string.ascii_lowercase + string.digits + string.ascii_uppercase)
                        for _ in range(5)) #generate 5 random characters
#run initScript
subprocess.Popen("python {}/python/initUser.py {} {}".format(
    os.getcwd(), uid,token), shell=True, stdin=None, stdout=None, stderr=None,
    close_fds=True)

print "Content-type: text/html"
print "Location: registerLoading.php?token={}".format(token)
print
sys.exit(0)
Run Code Online (Sandbox Code Playgroud)

进程线被盗:运行进程,不要等待

但是子流程线仍在阻塞,我无法弄清楚原因.

我正在开发ubuntu 16.04,它将在raspbarry pi 3上运行(这解释了加载时间)

phi*_*hag 9

close_fds对stdout没有影响.您需要devnull文件句柄(subprocess.DEVNULL在Python 3.3+中),以便通过调用关闭此脚本的stdout exit:

subprocess.Popen(
   ["python", "python/initUser.py", uid, token],
   stdin=None, stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
Run Code Online (Sandbox Code Playgroud)

请注意,我还用列表表单替换了shell命令.这使得代码可以安全地防止命令注入 - 以前,每个用户都可以在您的Web服务器上运行任意shell命令.

此外,您可能还想加强令牌的安全性.5个字符可以强制使用,但更重要的random.choice是,它不是加密安全的.random.SystemRandom().choice相反,使用secrets.token_urlsafePython 3.6+中更现代的.