在paramiko ssh连接中无密码执行su用户

2 投票
1 回答
7693 浏览
提问于 2025-04-17 07:54

我需要通过SSH登录到一个服务器,然后执行“su username”(不需要密码),以便以那个用户的身份执行一些命令(这个用户不能直接通过SSH登录)。

在终端上,这样做大概是这样的:

root@cs01:~# su foo
foo@cs01:/root$ cd
foo@cs01:~$ ls

我试着用paramiko(一个Python库)来实现这个:

import paramiko
ssh = paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

ssh.connect('host', username='root', password='mypassword', key_filename='<filename>')

stdin, stdout, stderr = ssh.exec_command('su foo')
print stdout.readlines()
stdin, stdout, stderr = ssh.exec_command('cd')
print stdout.readlines()
stdin, stdout, stderr = ssh.exec_command('pwd')
print stdout.readlines()
ssh.close()

但是这个脚本一直没有结束。

日志内容是这样的:

...
DEB [20111207-16:22:25.538] thr=1   paramiko.transport: userauth is OK
INF [20111207-16:22:25.921] thr=1   paramiko.transport: Authentication (publickey) successful!
DEB [20111207-16:22:25.923] thr=2   paramiko.transport: [chan 1] Max packet in: 34816 bytes
DEB [20111207-16:22:26.088] thr=1   paramiko.transport: [chan 1] Max packet out: 32768 bytes
INF [20111207-16:22:26.088] thr=1   paramiko.transport: Secsh channel 1 opened.
DEB [20111207-16:22:26.151] thr=1   paramiko.transport: [chan 1] Sesch channel 1 request ok

如果我只尝试这个:

stdin, stdout, stderr = ssh.exec_command('su foo')
#without print
stdin, stdout, stderr = ssh.exec_command('pwd')
print stdout.readlines()

它会以root用户的身份执行pwd命令,而不是以foo用户的身份。

这是什么问题呢?

1 个回答

8

每次调用 exec_command() 时,都会在一个新的命令行窗口中执行,所以之前的命令状态不会被保留。如果有的命令需要依赖于之前的命令才能执行,你就得把它们放在一个完整的语句里,或者写成一个脚本。如果你想要一个可以互动的命令行,可以使用 invoke_shell 命令,但这样的话你需要解析命令行的输出,以模拟互动使用(这里可以用到 pexpect 库)。

你可以使用 sudo 命令,或者 su -c 来执行命令。不过,我建议你为需要的用户配置一个安全的登录方式,然后直接以那个用户身份连接。

撰写回答