心得:走一步学一步,步步脚踏实地

Telnetlib模块:

总结一下关于如何连接服务器,主机,并且自动交互。

  1. 导入模块
  2. 实例化
  3. 查看系统
  4. 连接服务器
  5. 发送指令
  6. 接收结果
  7. 筛选数据
  8. 关闭连接

常使用源码的方法:

telnetlib.Telnet(host=ip,port=port) 实例化

read_very_eager()函数是telnetlib模块里的read方法,这里要设置延时time.sleep(1),才能保证数据读取完毕,使用延时得方法读取较好。

write() 连接之后写入命令

read_until('res',timeout=10)  设置等待结果和timeout

close() 关闭

1. 远程登录并循环执行命令

import logging
import telnetlib
import time


class TelnetClient():
    def __init__(self, ):
        self.tn = telnetlib.Telnet()

    # 此函数实现telnet登录主机
    def login_host(self, host_ip, username, password):
        try:
            # self.tn = telnetlib.Telnet(host_ip,port=23)
            self.tn.open(host_ip, port=23)
        except:
            logging.warning('%s网络连接失败' % host_ip)
            return False
        # 等待login出现后输入用户名,最多等待10秒
        self.tn.read_until(b'login: ', timeout=10)
        self.tn.write(username.encode('ascii') + b'\n')
        # 等待Password出现后输入用户名,最多等待10秒
        self.tn.read_until(b'Password: ', timeout=10)
        self.tn.write(password.encode('ascii') + b'\n')
        # 延时两秒再收取返回结果,给服务端足够响应时间
        time.sleep(2)
        # 获取登录结果
        # read_very_eager()获取到的是的是上次获取之后本次获取之前的所有输出
        command_result = self.tn.read_very_eager().decode('ascii')
        if 'Login incorrect' not in command_result:
            logging.warning('%s登录成功' % host_ip)
            return True
        else:
            logging.warning('%s登录失败,用户名或密码错误' % host_ip)
            return False

    # 此函数实现执行传过来的命令,并输出其执行结果
    def execute_some_command(self, command):
        # 执行命令
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(2)
        # 获取命令结果
        command_result = self.tn.read_very_eager().decode('ascii')
        logging.warning('命令执行结果:\n%s' % command_result)

    # 退出telnet
    def logout_host(self):
        self.tn.write(b"exit\n")

if __name__ == '__main__':
    host_ip = '192.168.220.129'
    username = 'root'
    password = 'abcd1234'
    command = 'whoami'
    telnet_client = TelnetClient()
    # 如果登录结果返加True,则执行命令,然后退出
    if telnet_client.login_host(host_ip, username, password):
        telnet_client.execute_some_command(command)
        telnet_client.logout_host()

2. 远程登录并执行

import platform
import subprocess
import telnetlib
import time

class Telnet():

    def __init__(self):
        self.conn = None
        self.encoding = 'utf-8'

    def enc(self, msg):
        return bytes(msg, encoding=self.encording)

    def dec(self,byte):
        return str(byte, encoding=self.encording)

    def ping_server(self):
        host=platform.system()
        if find("Linux") >=0:
            res=subprocess.getoutput('ping %s'%ip)
        elif find("Windos") >=0:
            res = subprocess.getoutput('ping %s' % ip)
        else:
            res = -1
        return res
    def connect(self,ip,port):
        self.ping_server()
        if self.ping_server() != -1:
        	self.conn = telnetlib.Telnet(ip, port)
        	self.login()
        else:
        	print('Error:connect server %s'%ip)

    def close(self):
        self.conn.close()

    def send(self,cmd):
        self.conn.write(self.enc(cmd))
        self.conn.write(self.enc("\n"))
        time.sleep(1)
        res=self.recv()

    def recv(self):
        res=self.conn.read_very_eager()
        res=self.dec(res)
        return res

    def login(self,username,password):
        self.conn.read_until(b'login: ', timeout=10)
        self.conn.send(username)
        self.conn.read_until(b'Password: ', timeout=10)
        self.conn.send(password)
        return "succeed"

if __name__ == "__main__":
    ip,port,cmd="","".""
    telnet=Telnet()
    telnet.connect(ip,port)
    telnet.send(cmd)
    telnet.close()

paramiko模块

paramiko用于连接linux机器

paramiko是一个基于python编写的、使用ssh协议的模块,跟xshell和xftp功能类似,支持加密与认证,可以上传下载和访问服务器的文件。可以利用paramiko模块写服务器脚本,在本地执行,比如持续更新代码,查看日志,批量配置集群等。paramiko 主要包含SSHClient和SFTPClient两个组件:

SSHClient

ssh服务会话的表示,通常用来执行命令,主要有connect、exec_command、load_system_host_keys和set_missing_host_key_policy方法。
connect:建立SSH远程连接并校验。
exec_command:执行指令并返回结果。
set_missing_host_key_policy:远程主机没有本地主机密钥或HostKeys时的策略。

SFTPClient
SFTP客户端对象,实现远程文件操作,主要有from_transport、put、get、Mkdir、remove、rename、stat、listdir等方法。
from_transport:从已通过验证的传输对象简历连接。
put:上传本地文件到服务器上。
get:从服务器下载文件到本地。
Mkdir、remove、rename、stat、listdir:创建目录、删除目录、重命名文件或目录、获取文件信息、获取指定目录中的列表。

1. 远程执行命令

import paramiko

ssh = paramiko.SSHClient()  # 创建SSH对象
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='10.0.100.1', port=22, username='root', password='123456')
stdin, stdout, stderr = ssh.exec_command('ls')  # 执行命令
result = stdout.read()  # 获取命令结果
print(str(result, encoding='utf-8'))
ssh.close()  # 关闭连接

2. 上传文件

import paramiko

tran = paramiko.Transport(('xx.xx.xx.xx', 22))  
tran.connect(username="root", password='xxx') 
sftp = paramiko.SFTPClient.from_transport(tran)
localpath = "./your_name.log"
remotepath = "/root/platform/"
filename="your_name.log"
sftp.put(localpath, os.path.join(remotepath,filename))
tran.close()

3. 下载文件

import paramiko

tran = paramiko.Transport(('xx.xx.xx.xx', 22))
tran.connect(username="root", password='xxx')
sftp = paramiko.SFTPClient.from_transport(tran)
localpath = "./your_name_szj.log"
remotepath = "/root/platform"
filename="your_name.log"
sftp.get(remotepath,  os.path.join(remotepath,filename))
tran.close()

4. invoke_shell和linux交互操作

通过SSHClient的invoke_shell方法,可以创建一个交互会话的对象,和exec_command方法不同的是,这个可以实现命令交互,比如先cd到某个目录下,再执行脚本操作,然后退出,这种需要多个步骤的操作。

用法:

ssh = client.invoke_shell()
ssh.send(cmd+"\n")
ssh.recv(“多少内容”).decode(‘utf-8’)
ssh.recv.ready() 返回bool值

import paramiko

hostname = "10.0.100.1"
port = 22
username = "root"
password = "root"
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname, port, username, password, compress=True)
channel = client.invoke_shell()  # 在SSH server端创建一个交互式的shell
command = ""
channel.send(command + '\n')
time.sleep(1)
stdout = channel.recv(1024 * 100000) #返回多大的内容
out_list = stdout.decode('utf-8').split("\n")
client.close()

5. 类方法实现

import platform
import subprocess
import paramiko
import time

class Ssh():

    def __init__(self):
        self.conn = None
        self.channel = None
        self.encoding = 'utf-8'

    def enc(self, msg):
        return bytes(msg, encoding=self.encording)

    def dec(self,byte):
        return str(byte, encoding=self.encording)

    def ping_server(self):
        host=platform.system()
        if find("Linux") >=0:
            res=subprocess.getoutput('ping %s'%ip)
        elif find("Windos") >=0:
            res = subprocess.getoutput('ping %s' % ip)
        else:
            res = -1
        return res

    def connect(self,hostname,port,username,password):
        self.conn = client = paramiko.SSHClient()
        self.conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        if self.ping_server() != -1:
            self.conn.connect(hostname, port, username, password, compress=True)
            self.channel= self.conn.invoke_shell()

    def close(self):
        self.channel.send('exit\n')
        self.conn.close()

    def send(self,cmd):
        self.channel.send(self.enc(cmd))
        self.channel.send(self.enc("\n"))
        time.sleep(1)
        res=self.recv()
        return res

    def recv(self):
        res=self.channel.recv(1024*1000)
        res=self.dec(res)
        return res
       
	def upload(self,ip,username,password):
		tran = paramiko.Transport((ip, 22))  
		tran.connect(username=username, password=password) 
		sftp = paramiko.SFTPClient.from_transport(tran)
		localpath = "./your_name.log"
		remotepath = "/root/platform/"
		filename="your_name.log"
		sftp.put(localpath, os.path.join(remotepath,filename))
		tran.close()
    
    def download(self,ip,username,password):
		tran = paramiko.Transport((ip, 22))  
		tran.connect(username=username, password=password) 
		sftp = paramiko.SFTPClient.from_transport(tran)
		localpath = "./your_name.log"
		remotepath = "/root/platform/"
		filename="your_name.log"
		sftp.get(localpath, os.path.join(remotepath,filename))
		tran.close()
if __name__ == "__main__":
    ip,port,user,passwd="","","",""
    ssh=Ssh()
    ssh.connect(ip,port,user,passwd)
    ssh.send(cmd)
    ssh.close()
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐