我有一个处理登录的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 Process and Don't Wait
但是子进程线仍在阻塞,我无法弄清楚原因。
我正在开发ubuntu 16.04,它将在raspbarry pi 3上运行(这解释了加载时间)
答案 0 :(得分:8)
close_fds
对stdout没有影响。您需要devnull文件句柄(Python 3.3+中的subprocess.DEVNULL
),以便通过调用exit
关闭此脚本的标准输出:
subprocess.Popen(
["python", "python/initUser.py", uid, token],
stdin=None, stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
请注意,我还用列表表单替换了shell命令。这使得代码对command injection安全 - 以前,每个用户都可以在您的网络服务器上运行任意shell命令。
此外,您可能还想加强令牌的安全性。 5个字符可以强制使用,但更重要的是,random.choice
不具有加密安全性。请改用random.SystemRandom().choice
,或使用Python 3.6 +中更现代的secrets.token_urlsafe
。