如何让python脚本给sudo提示我的密码

时间:2017-12-19 06:42:08

标签: python linux sudo

我在python 3.6中编写了一个使用许多sudo命令的脚本。该脚本作为我的用户在linux机器上运行。该脚本正在创建一种报告,对许多服务器执行ssh并运行lsof等命令 我需要一种方法让python在我使用sudo时随时提供密码。显然,在我第一次输入密码时,它可以保存在脚本的内存中。 我一直在使用python子进程来运行我的sudo命令,例如:

cmd = SSH + '-t ' + source + " ' " + SUDO + "-k " +  LSOF + "-p " + pid + " ' "
output = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
(out,error) = output.communicate()

有可能吗?

限制:
根套件不允许
使用sudo运行脚本不是一个选项,因为脚本会ssh到许多服务器,出于安全考虑,我不允许这样做。
无法改变sudoers文件中的任何内容。

5 个答案:

答案 0 :(得分:1)

我建议你使用Python的“pexpect”模块来做到这一点。 它基于“期望”并用于自动化与其他程序的交互。 它不是python标准库的一部分,但如果您创建自己的python环境,则不一定需要root来安装它。

示例:

#import the pexpect module
import pexpect
# here you issue the command with "sudo"
child = pexpect.spawn('sudo /usr/sbin/lsof')
# it will prompt something like: "[sudo] password for < generic_user >:"
# you "expect" to receive a string containing keyword "password"
child.expect('password')
# if it's found, send the password
child.sendline('S3crEt.P4Ss')
# read the output
print(child.read())
# the end

更多细节可以在这里找到:

https://pexpect.readthedocs.io/en/stable/api/index.html

希望这有帮助!

答案 1 :(得分:0)

因为您想为您的python脚本提供sudo密码,所以我认为最好创建一个新用户组并将此组设置为您的脚本文件。您的脚本不再需要sudo密码(仍有sudo权限)。

注意:(我的答案在Ubuntu 14.04上测试。另一个Linux版本应该是相同的。

如果您以root用户身份登录,则可以通过键入以下内容随时创建新用户:

adduser <newuser>

sudo adduser <newuser>

如果您的新用户应该能够执行具有root(管理)权限的命令,则需要授予新用户sudo的访问权限。

我们可以使用visudo命令执行此操作,该命令会在编辑器中打开相应的配置文件。这是进行这些更改的最安全方法。

visudo

sudo visudo

搜索如下所示的行:

root    ALL=(ALL:ALL) ALL

在此行下方,复制您在此处看到的格式,仅更改“root”一词,以引用您希望赋予sudo权限的新用户:

root      ALL=(ALL:ALL) ALL
<newuser> ALL=(ALL) NOPASSWD:ALL

使用chown更改python脚本的所有权。

sudo chown <newuser>: <python script>

之后,您可以在sudo权限下运行您的脚本而无需密码。

注意:(我建议你这样做,因为你想把你的sudo密码放到源代码中。但是,请注意你的脚本。它有更强大的功能...

答案 2 :(得分:0)

我认为你应该使用Paramiko库来做到这一点。确保在导入之前安装paramiko。 Check this

以下是示例代码。在使用它之前测试它。

$pip install paramiko

import paramiko
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
pid = 12345 # Modify this per your requirement
try:
    ssh_client.connect('source',username='user',password='pwd')
    stdin,stdout,stderr = ssh_client.exec_command('sudo -k lsof -p '+pid)
    stdin.write('pwd\n')
    stdin.flush()
    result = stdout.read.splitlines()
except paramiko.SSHException:
    print('Connection Failed')
    quit()

答案 3 :(得分:0)

花几个小时弄清楚如何使用子流程。

所以享受:

import getpass
import subprocess

sudo_password = getpass.getpass(prompt='sudo password: ')
p = subprocess.Popen(['sudo', '-S', 'ls'], stderr=subprocess.PIPE, stdout=subprocess.PIPE,  stdin=subprocess.PIPE)

try:
    out, err = p.communicate(input=(sudo_password+'\n').encode(),timeout=5)

except subprocess.TimeoutExpired:
    p.kill()

答案 4 :(得分:0)

以下答案执行三种尝试来验证访问权限:

  • 检查当前用户是否为root
  • 在不提供密码的情况下致电sudo
  • 询问用户密码并致电sudo

sudo的调用将调用echo命令,并检查应该由echo打印的同一测试:单词OK

import os, subprocess
from getpass import getpass

def is_root():
    return os.geteuid() == 0

def test_sudo(pwd=""):
    args = "sudo -S echo OK".split()
    kwargs = dict(stdout=subprocess.PIPE,
                  encoding="ascii")
    if pwd:
        kwargs.update(input=pwd)
    cmd = subprocess.run(args, **kwargs)
    return ("OK" in cmd.stdout)

def prompt_sudo():
    ok = is_root() or test_sudo()
    if not ok:
        pwd = getpass("password: ")
        ok  = test_sudo(pwd)
    return ok

if prompt_sudo():
    print("Access granted !")
else:
    print("Access denied !")