如何在Paramiko中单个会话执行多个命令?(Python)

55 投票
8 回答
127548 浏览
提问于 2025-04-16 18:46
def exec_command(self, command, bufsize=-1):
    #print "Executing Command: "+command
    chan = self._transport.open_session()
    chan.exec_command(command)
    stdin = chan.makefile('wb', bufsize)
    stdout = chan.makefile('rb', bufsize)
    stderr = chan.makefile_stderr('rb', bufsize)
    return stdin, stdout, stderr

在使用paramiko执行命令时,每次运行exec_command都会重置会话。我希望能够执行sudo或su命令,并在后续运行另一个exec_command时仍然保持这些权限。再举个例子,如果我执行exec_command("cd /"),然后再运行exec_command,期望它能在根目录下。我知道可以像这样执行exec_command("cd /; ls -l"),但我需要在不同的函数调用中实现这个功能。

8 个回答

20

严格来说,你是不能这样做的。根据ssh的规范:

一个会话就是远程执行一个程序。这个程序可以是一个 shell(命令行)、一个应用程序、一个系统命令,或者某个内置的子系统。

这意味着,一旦命令执行完毕,这个会话就结束了。你不能在一个会话中执行多个命令。不过,你可以做的是启动一个远程的shell(也就是执行一个命令),然后通过标准输入等与这个shell进行互动……(可以想象成执行一个python脚本和运行交互式解释器的区别)

23

试着创建一个用 \n 字符分开的命令字符串。这对我有效。比如说,你可以这样写:ssh.exec_command("command_1 \n command_2 \n command_3")

50

非交互式使用案例

这是一个非交互式的例子……它发送了cd tmpls,然后exit

import sys
sys.stderr = open('/dev/null')       # Silence silly warnings from paramiko
import paramiko as pm
sys.stderr = sys.__stderr__
import os

class AllowAllKeys(pm.MissingHostKeyPolicy):
    def missing_host_key(self, client, hostname, key):
        return

HOST = '127.0.0.1'
USER = ''
PASSWORD = ''

client = pm.SSHClient()
client.load_system_host_keys()
client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
client.set_missing_host_key_policy(AllowAllKeys())
client.connect(HOST, username=USER, password=PASSWORD)

channel = client.invoke_shell()
stdin = channel.makefile('wb')
stdout = channel.makefile('rb')

stdin.write('''
cd tmp
ls
exit
''')
print stdout.read()

stdout.close()
stdin.close()
client.close()

交互式使用案例

如果你有一个需要交互的ssh使用场景,paramiko可以处理这个……我个人会用scrapli来进行交互式ssh会话。

以下是我想到的所有可以交互使用paramiko的方法:

我可能遗漏了一些使用paramiko的库,但很明显,paramiko在控制ssh会话的python库中被广泛使用。

撰写回答