我在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文件中的任何内容。
我建议你使用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
希望这可以帮助!
因为您想为您的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
密码放到源代码中。但是,请小心你的脚本。它有更强大的...)
我认为你应该使用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()