python - 如何保持 ssh 连接打开并在 python 中执行多个请求和输出
问题描述
因为这个问题似乎针对其他地方,所以我将在这里指出我的问题:
在我的 python 脚本中,我使用 ssh 对远程服务器使用多个请求:
def ssh(command):
command = 'ssh SERVER "command"'
output = subprocess.check_output(
command,
stderr=subprocess.STDOUT,
shell=True,
universal_newlines=True
)
return output
在这里我会得到file1
as的内容output
。
我现在有多种使用此功能的方法:
def show_one():
ssh('cat file1')
def show_two():
ssh('cat file2')
def run():
one = show_one()
print(one)
two = show_two()
print(two)
执行run()
将打开和关闭每个show_*
方法的 ssh 连接,这使得它非常慢。
解决方案:
- 我可以说:
Host SERVER
ControlMaster auto
ControlPersist yes
ControlPath ~/.ssh/socket-%r@%h:%p
进入我的.ssh/config
,但我想在 python 中解决这个问题。
有 ssh 标志
-T
来保持连接打开,在前面提到的问题中,一个答案是使用它Popen()
,p.communicate()
但是不可能在两者之间获得输出,communicates
因为它会引发错误ValueError: Cannot send input after starting communication
我可以以某种方式更改我的函数以执行单个 ssh 命令,
echo "--show1--"; cat file1; echo "--show2--"; cat file2
但这对我来说看起来很老套,我希望有更好的方法来保持 ssh 连接打开并像平常一样使用它。我想要的:例如一个 pythonic/bashic 做同样的事情,我可以在
.ssh/config
(见1.
)中配置来声明一个特定的套接字用于连接并显式打开、使用、关闭它
解决方案
尝试从类创建 ssh 对象并将其传递给函数:
import paramiko
from pythonping import ping
from scp import SCPClient
class SSH():
def __init__(self, ip='192.168.1.1', username='user', password='pass',connect=True,Timeout=10):
self.ip = ip
self.username = username
self.password = password
self.Timeout=Timeout
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if connect:
self.OpenConnection()
self.scp = SCPClient(self.ssh.get_transport())
def OpenConnection(self):
try:
skip_ping = False
ping_res=False
log.info('Sending ping to host (timeout=3,count=3) :'+self.ip)
try:
PingRes = ping(target=self.ip,timeout=3,count=3, verbose=True)
log.info('Ping to host result :' + str(PingRes.success()))
ping_res=PingRes.success()
except:
skip_ping=True
if ping_res or skip_ping:
log.info('Starting to open connection....')
self.ssh.connect(hostname=self.ip, username=self.username, password=self.password, timeout=self.Timeout, auth_timeout=self.Timeout,banner_timeout=self.Timeout)
self.scp = SCPClient(self.ssh.get_transport())
log.info('Connection open')
return True
else:
log.error('ssh OpenConnection failed: No Ping to host')
return False
myssh = SSH(ip='192.168.1.1',password='mypass',username='myusername')
ping 结果包含在 try catch 中,因为有时我的机器会返回错误,您可以将其删除并验证对主机的 ping。self.scp 用于文件传输。
推荐阅读
- git - 为什么 git fetch 似乎并没有真正获取最新的远程提交?
- javascript - Node.js 和 Jest TypeError 与 supertest
- mysql - (Python MySQL)如何将 LIKE 通配符与变量一起使用?
- erlang - Erlang JInterface:OtpNode vs OtpSelf
- flutter - Flutter redux:StoreConnector vs StoreProvider
- awk - 使用 FPAT Var 删除逗号后的空格
- sql - 累计持股
- php - 使用 html 表单和 php 将记录插入 MySQL 数据库(在线)失败,没有错误消息
- python - Python:pandas.cut 标签被忽略
- xcode - 无法找到“UMReactNativeAdapter”依赖的“React-Core”规范