如何在Paramiko中单个会话执行多个命令?(Python)
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 tmp
、ls
,然后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
的方法:
- 查看nagabhushan的回答,其中使用了交互式的
paramiko
- 默认情况下,ansible的paramiko用法是可配置的
- 默认情况下,exscript的ssh使用paramiko
- 默认情况下,netmiko的ssh使用paramiko
- 默认情况下,scrapli的ssh使用paramiko