题
所以我试图让一个过程中要使用子python脚本中运行的超级用户。在IPython的壳像
proc = subprocess.Popen('sudo apach2ctl restart',
shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
工作正常,但只要我坚持到脚本中我开始得到。sudo: apach2ctl: command not found
我猜想到须藤的方式处理在Ubuntu环境,这是由于。 (我也尝试sudo -E apche2ctl restart
和sudo env path=$PATH apache2ctl restart
与无济于事)
所以我的问题基本上是,如果我想有需要时,提示用户为超级用户密码,超级用户运行apache2ctl restart
,我应该如何去这样做?我没有在脚本存储密码的意图。
编辑:
我试图传递的命令同时作为字符串和记号化到一个列表中。在Python解释器,用绳子,我会得到密码提示正确(在Python脚本仍然不起作用在我原来的问题),一个列表只是提供了帮助屏幕sudo的。
编辑2:
所以我收集的是,虽然POPEN将一些命令,就像串工作时,壳=真,它需要
proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart'])
没有 '壳=真' 来获得须藤工作。
谢谢!
解决方案
先给的完整路径apache2ctl。
其他提示
尝试:
subprocess.call(['sudo', 'apach2ctl', 'restart'])
在子需要访问真正的标准输入/输出/ ERR它能够提示你,并在你的密码读取。如果将它们设置为管道,你需要密码送入该管自己。
如果你不定义它们,然后将其抓住sys.stdout的,等等...
另一种方法是使用户密码更少sudo user
。
键入以下命令行:
sudo visudo
然后添加以下和替换与你的<username>
:
<username> ALL=(ALL) NOPASSWD: ALL
这将允许用户无需索要密码(包括应用程序通过上述用户推出执行sudo
命令。这可能是一个安全隐患,虽然
您必须使用POPEN这样的:
cmd = ['sudo', 'apache2ctl', 'restart']
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
有期望的列表。
我用这对蟒3.5。我做到了使用的 子 强> module.Using的像这样的密码是非常的不安全强>
在子模块占用命令为字符串的列表,以便可以创建预先使用列表的分裂()或以后通过的整个列表。阅读文档的详细信息。
我们这里做的是呼应的密码,然后使用管:我们把它传递给通过“-S”的说法须藤。
#!/usr/bin/env python
import subprocess
sudo_password = 'mysecretpass'
command = 'apach2ctl restart'
command = command.split()
cmd1 = subprocess.Popen(['echo',sudo_password], stdout=subprocess.PIPE)
cmd2 = subprocess.Popen(['sudo','-S'] + command, stdin=cmd1.stdout, stdout=subprocess.PIPE)
output = cmd2.stdout.read().decode()
我尝试了所有的解决方案,但没有奏效。想跑芹菜长时间运行的任务,但对这些I需要运行与subprocess.call()须藤chown命令。
这是对我工作:
要添加安全的环境变量,在命令行键入:
export MY_SUDO_PASS="user_password_here"
要测试是否它的工作类型:
echo $MY_SUDO_PASS
> user_password_here
要在系统启动时运行它把它添加到该文件的末尾:
nano ~/.bashrc
#.bashrc
...
existing_content:
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
...
export MY_SUDO_PASS="user_password_here"
您可以添加所有你的环境变量密码,用户名,主机,等晚一点。
如果您的变量是准备好你可以运行:
要更新:
echo $MY_SUDO_PASS | sudo -S apt-get update
,或安装午夜指挥官
echo $MY_SUDO_PASS | sudo -S apt-get install mc
要与须藤开始午夜指挥官
echo $MY_SUDO_PASS | sudo -S mc
或者从蟒壳(或Django的/芹菜),改变目录所有权递归:
python
>> import subprocess
>> subprocess.call('echo $MY_SUDO_PASS | sudo -S chown -R username_here /home/username_here/folder_to_change_ownership_recursivley', shell=True)
希望它能帮助。
要做到这一点的最安全的方法是将其提示用户输入密码事先然后通过管道进入命令。提示输入密码将避免密码在你的代码的任何地方保存,也不会在你的bash的历史显示。下面是一个例子:
from getpass import getpass
from subprocess import Popen, PIPE
password = getpass("Please enter your password: ")
# sudo requires the flag '-S' in order to take input from stdin
proc = Popen("sudo -S apach2ctl restart".split(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
# Popen only accepts byte-arrays so you must encode the string
proc.communicate(password.encode())