在Django中执行shell命令

5 投票
3 回答
32614 浏览
提问于 2025-04-15 23:56

我正在用Django开发一个网页(使用apache服务器),需要调用一个命令来启用或禁用一些后台服务。我尝试用这个命令:

os.system(service httpd restart 1>$HOME/out 2>$HOME/error)

但是这个命令没有返回任何结果。有没有什么办法可以解决这个问题?

3 个回答

3

这是我在我的一个Django应用中用来启动进程的代码:

  import subprocess
  process = subprocess.Popen(['python', 'manage.py', 'some_command'])

在你的情况下,代码应该是:

import subprocess     
process = subprocess.Popen(['service', 'httpd', 'restart'])

(另外,你还需要处理标准输出和错误输出 - 不确定加上 '1>$HOME/out' 是否能在 Popen 中正常工作。这里有一个关于 子进程的文档

4

试着在命令行中运行这个命令:

import subprocess
r = subprocess.call("service httpd restart 1>$HOME/out 2>$HOME/error", shell=True)
10

我就不多说了,关于让一个网络应用去启动和停止系统进程的风险,直接回答你的问题吧。

你的 Django 应用不应该以 root 用户身份运行,因为这可能需要启动和停止服务。你可以通过以下方式来解决这个问题:

  • 创建一个使用 seteuid 的脚本
  • 给这个文件设置 set uid 属性

这个脚本大概是这样的:

#!/usr/bin/python <- or wherever your python interpreter is
import os
os.seteuid(0)
os.system("service httpd restart 1>$HOME/out 2>$HOME/error")

要允许将有效用户 ID 设置为 root(0),你需要在终端中以 root 身份运行:

chown root yourscript.py
chmod u+s yourscript.py
chmod a+x yourscript.py

这样就可以了。在你的 Django 应用中,你现在可以调用 os.system('yourscript.py') 来以 root 权限运行这个命令。

最后,我觉得你传给 os.system() 的命令可能不是你想要的,因为你提到要启用和禁用守护进程,而你现在做的只是重启 apache……而这似乎是你的 Django 应用运行的地方,所以实际上你是在杀掉自己的网络应用。

撰写回答