从Django运行shell命令

Bad*_*nky 3 python apache django

我正在Django中开发一个网页(使用apache服务器),需要调用shell命令来启用/禁用某些守护进程.我试着这样做

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

并且此命令不返回任何内容.知道我该如何解决这个问题?

Mig*_*ura 7

我将跳过我强烈建议您使用Web应用程序启动和停止系统进程并尝试回答问题的含义的部分.

您的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")
Run Code Online (Sandbox Code Playgroud)

要允许将有效UID设置为root(0),您必须在shell中以root身份运行:

chown root yourscript.py
chmod u+s yourscript.py
chmod a+x yourscript.py
Run Code Online (Sandbox Code Playgroud)

应该这样做.在您的Django应用程序中,您现在可以调用os.system('yourscript.py')以root权限运行该命令.

最后,我相信你传递的命令os.system()不是你想要的,因为你谈论启用和禁用守护进程,而你正在做的就是重新启动apache ...这反过来似乎是你的地方django正在运行,所以在实践中你会杀死你自己的webapp.

  • 这对大多数用户不起作用,因为出于安全原因,脚本中不允许使用seteuid操作.如果它确实有效,任何人都可以做"python -c'import os; os.setuid(0); os.setgid(0); os.system("sh")'"让自己成为root shell! (3认同)

dzi*_*ida 3

以下是我用于从我的 django 应用程序之一启动进程的代码:

  import subprocess
  process = subprocess.Popen(['python', 'manage.py', 'some_command'])
Run Code Online (Sandbox Code Playgroud)

在你的情况下,它将是:

import subprocess     
process = subprocess.Popen(['service', 'httpd', 'restart'])
Run Code Online (Sandbox Code Playgroud)

(您还需要处理 stdout 和 stderr - 不确定添加 '1>$HOME/out' 是否可以与 Popen 一起使用。有子流程的文档

  • 为什么要使用“subprocess”而不是内置的 Django“call_command”方法来运行“./manage.py some_command”?请参阅此处的完整建议解决方案:/sf/answers/2804439781/ (2认同)