如何在Paramiko中使用sudo?(Python)

19 投票
8 回答
67078 浏览
提问于 2025-04-16 19:07

我尝试过的事情:

  1. invoke_shell()命令,然后用channel.send发送su和密码,结果没有获得管理员权限。
  2. invoke_shell()后接channel.exec_command,结果出现了“通道关闭”的错误。
  3. _transport.open_session()后接channel.exec_command,结果也没有获得管理员权限。
  4. invoke_shell()后写入标准输入并刷新,结果还是没有获得管理员权限。

8 个回答

6

AlexS 的详细回答(我现在在实际使用中)是:

def sudo_run_commands_remote(command, server_address, server_username, server_pass, server_key_file):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname=server_address,
                username=server_username,
                password=server_pass,
                key_filename=server_key_file)
    session = ssh.get_transport().open_session()
    session.set_combine_stderr(True)
    session.get_pty()
    session.exec_command("sudo bash -c \"" + command + "\"")
    stdin = session.makefile('wb', -1)
    stdout = session.makefile('rb', -1)
    stdin.write(server_pass + '\n')
    stdin.flush()
    print(stdout.read().decode("utf-8"))

如果你不使用密钥文件,就把 connect 方法中的 key_filename 部分去掉;如果你只用密钥而没有密码,那就把 password 部分去掉。

这里有几点需要注意,这个方法支持多条命令。也就是说,它以 root 身份运行 bash,你可以在一次运行中输入尽可能多的命令,只需用 ; 分隔开即可。

8

invoke_shell对我来说是这样工作的:

import paramiko, getpass, re, time

ssh_client = paramiko.SSHClient()   
ssh_client.connect( host )
sudo_pw = getpass.getpass("sudo pw for %s: " % host)
command = "sudo magicwand"

channel = ssh_client.invoke_shell() 
channel.send( command )       
# wait for prompt             
while not re.search(".*\[sudo\].*",channel.recv(1024)): time.sleep(1)
channel.send( "%s\n" % sudo_pw )
27

看看这个例子:

ssh.connect('127.0.0.1', username='jesse', 
    password='lol')
stdin, stdout, stderr = ssh.exec_command(
    "sudo dmesg")
stdin.write('lol\n')
stdin.flush()
data = stdout.read.splitlines()
for line in data:
    if line.split(':')[0] == 'AirPort':
        print line

这里有个例子,里面有更多的解释: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

希望对你有帮助!

撰写回答