python - 为什么 subprocess.Popen 阻塞?

标签 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 Process and Don't Wait

但是子进程线仍然阻塞,我不明白为什么。

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

最佳答案

close_fds 对标准输出没有影响。您需要 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 命令。

此外,您可能还想加强 token 的安全性。 5 个字符可以被暴力破解,但更重要的是,random.choice 不是加密安全的。使用 random.SystemRandom().choice相反,或者更现代的secrets.token_urlsafe在 Python 3.6+ 中。

关于python - 为什么 subprocess.Popen 阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49310057/

相关文章:

Python、Ubuntu : Install PyPi package for a specific Python version

python - 模块 're' 没有属性 'findall'

python等待shell命令完成

python - 如何获取子进程的 stderr 流输出的最后 N 行?

Python 子进程被 "echo y"管道破坏

python - 如果我在 subprocess.Popen() 中不使用 stdout=subprocess.PIPE 有什么区别?

Python 在 sudo 中调用 bash 脚本的子进程

python - 如何方便地读取python中的数字?

python - 两个 timedelta 对象的差异,带有时区

Windows 上的 Python Popen、close_fds 和重定向输入/输出