从python脚本以超级用户身份运行命令

Sil*_*eed 41 python sudo subprocess

因此,我正在尝试使用子进程从python脚本中以超级用户身份运行进程.在ipython shell中就像是

proc = subprocess.Popen('sudo apach2ctl restart',
                        shell=True, stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

工作正常,但一旦我把它插入脚本,我开始得到:sudo: apach2ctl: command not found.

我猜这是由于sudo在ubuntu上处理环境的方式.(我也尝试sudo -E apche2ctl restartsudo env path=$PATH apache2ctl restart与无济于事)

所以我的问题基本上是,如果我想以apache2ctl restart超级用户身份运行,在需要时提示用户输入超级用户密码,我应该怎么做呢?我无意在脚本中存储密码.

编辑:

我已经尝试将命令作为字符串传递并标记为列表.在python解释器中,使用字符串我将正确地获得密码提示(仍然不像我原来的问题那样在python脚本中工作),列表只是给出了sudo的帮助屏幕.

编辑2:

所以我收集的是,当shell = True时,Popen将使用一些命令作为字符串,这需要

proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart'])
Run Code Online (Sandbox Code Playgroud)

没有'shell = True'让sudo工作.

谢谢!

Mik*_*ers 25

尝试:

subprocess.call(['sudo', 'apach2ctl', 'restart'])

子进程需要访问真正的stdin/out/err才能提示您,并读入您的密码.如果将它们设置为管道,则需要自己将密码提供给该管道.

如果你没有定义它们,那么它会抓取sys.stdout等...

  • 您没有解决密码问题,如下解决。 (4认同)

dwc*_*dwc 17

尝试给出apache2ctl的完整路径.


Mic*_*Loo 12

另一种方法是让您的用户无密码sudo user.

在命令行上键入以下内容:

sudo visudo
Run Code Online (Sandbox Code Playgroud)

然后添加以下内容并替换为<username>您的:

<username> ALL=(ALL) NOPASSWD: ALL
Run Code Online (Sandbox Code Playgroud)

这将允许用户执行sudo命令而不必询问密码(包括由所述用户启动的应用程序.这可能是安全风险,尽管


Nan*_*esh 9

我将它用于 python 3.5。我使用进程模块做到了。使用这样的密码是非常不安全的

模块将命令作为字符串的列表,以便可以创建一个列表预先使用()分裂或以后通过的整个列表。阅读文档以获取更多信息。

我们在这里所做的是回显密码,然后使用管道我们通过“-S”参数将其传递给 sudo。

#!/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() 
Run Code Online (Sandbox Code Playgroud)


Har*_*mbe 6

您必须像这样使用Popen:

cmd = ['sudo', 'apache2ctl', 'restart']
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

它期望一个列表。

  • 阅读http://docs.python.org/library/subprocess.html当shell = True时,字符串和序列args之间存在区别。 (9认同)
  • 将列表传递到其中时,请勿设置shell = True。 (3认同)

Jos*_*eia 5

最安全的方法是事先提示输入密码,然后通过管道将其输入到命令中。提示输入密码将避免将密码保存在代码中的任何位置,并且它也不会出现在您的 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())
Run Code Online (Sandbox Code Playgroud)