简体   繁体   English

从Django运行shell命令

[英]Run a shell command from Django

I'm developing a web page in Django (using apache server) that needs to call a shell command to enable/dissable some daemons. 我正在Django中开发一个网页(使用apache服务器),需要调用shell命令来启用/禁用某些守护进程。 I'm try to do it with 我试着这样做

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

and this command doesn't return anything. 并且此命令不返回任何内容。 Any idea how can i fix this? 知道我该如何解决这个问题?

I'll skip the part where I strongly advise you about the implications of having a web application starting and stopping system processes and try to answer the question. 我将跳过我强烈建议您使用Web应用程序启动和停止系统进程并尝试回答问题的含义的部分。

Your django application shouldn't run with root user, which should probably be needed to start and stop services. 您的django应用程序不应与root用户一起运行,这可能是启动和停止服务所必需的。 You can probably overcome this by: 您可以通过以下方式克服此问题

  • creating a script that uses seteuid 创建一个使用seteuid的脚本
  • give that file the set uid attribute 给该文件设置set uid属性

The script would be something like 脚本就像是

#!/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")

To allow setting the effective UID to root (0), you have to run, in a shell, as root: 要允许将有效UID设置为root(0),您必须在shell中以root身份运行:

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

That should do it. 应该这样做。 In your Django app you can now call os.system('yourscript.py') to run the command with root permissions. 在您的Django应用程序中,您现在可以调用os.system('yourscript.py')来运行具有root权限的命令。

Finally, I believe that the command you're passing to os.system() isn't what you're looking for, since you talk about enabling and disabling daemons and all you're doing is restarting apache... which in turn seems to be where your django is running, so in practice you'll be killing your own webapp. 最后,我相信你传递给os.system()的命令不是你想要的,因为你谈到启用和禁用守护进程,而你正在做的就是重新启动apache ......反过来似乎是你的django正在运行的地方,所以在实践中你将会杀死你自己的webapp。

Try run the command in Shell: 尝试在Shell中运行命令:

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

Here is the code I use for launching process from my one of my django app: 这是我从我的django应用程序启动过程中使用的代码:

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

In your case it would be: 在你的情况下,它将是:

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

(also you need to handle stdout and stderr - not sure if adding '1>$HOME/out') would work with Popen. (你还需要处理stdout和stderr - 不确定添加'1> $ HOME / out')是否适用于Popen。 There is documentation for subprocess 子进程的文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM