Python实用工具,paramiko模块,实现简易版SSH登录工具

585 阅读3分钟

开发工具

Python版本:3.5.4
相关模块:
paramiko模块以及一些Python自带的模块。
操作系统:
Windows系列。

image.png

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

主要思路

目的:
制作命令行版的SSH登录工具。
需要实现的功能:
(1)添加/删除连接服务器需要的IP、端口、密码;
(2)自动输入密码登录远程服务器。

相关代码

auto_ssh.py

# 自动登录远程服务器
import os
import base64
import sys
import paramiko
path = os.path.dirname(os.path.abspath(sys.argv[0]))


def ssh_connect(host_ip, host_port, username, password):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(host_ip, host_port, username, password, allow_agent=False, look_for_keys=False)
        print('[INFO]:Connect Successfully...')
    except:
        print('[INFO]:Fail to Connect...')
    while True:
        command = input('Enter the command(<#q> exit):')
        if command.strip() == '#q':
            ssh.close()
            return
        stdin, stdout, stderr = ssh.exec_command(command)
        out_content = stdout.readlines()
        if len(out_content) < 1:
            print('Error:')
            print(stderr.readlines())
        else:
            print('Result:')
            for o in out_content:
                print(o)



def choose_host():
    f = open("{}/data/info.d".format(path))
    hosts = f.readlines()
    hosts_temp = []
    for h in hosts:
        if h.strip():
            hosts_temp.append(h)
    hosts = hosts_temp[:]
    hosts_len = len(hosts)
    if hosts_len <= 0:
        os.system('cls')
        print('[Warning]:No info saved before...')
        return
    while True:
        print('SSH......')
        print('FORMAT:\nAlias UserName@IP: PORT')
        for i in range(0, hosts_len):
            line_list = hosts[i].strip().split(' ')
            print("<{}>: {} |{}@{}: {}|".format(i+1, line_list[4], line_list[2], line_list[0], line_list[1]))
        choice = input('[SSH]:Choose the number or alias(<#q> exit):')
        is_alias = False
        is_num = False
        try:
            choice = int(choice)
            if choice < 1 or choice > hosts_len:
                os.system('cls')
                print('[Warning]:Number inexistence...')
                continue
            line_list = hosts[choice-1].split(' ')
            username = line_list[2]
            password = line_list[3]
            host_ip = line_list[0]
            host_port = line_list[1]
            is_num = True
        except:
            is_alias = True
        if is_alias:
            if choice.strip() == '#q':
                os.system('clear')
                return
            for h in hosts:
                if choice.strip() == h.split(' ')[4].strip():
                    line_list = h.split(' ')
                    username = line_list[2]
                    password = line_list[3]
                    host_ip = line_list[0]
                    host_port = line_list[1]
                    is_num = True
        if not is_num:
            os.system('cls')
            print('[Warning]:Alias inexistence...')
            continue
        # password = base64.decodestring(password)
        print('Start to connect {}@{}...'.format(username, host_ip))
        ssh_connect(host_ip, host_port, username, password)

settings.py

# 信息保存/删除/输出
import base64
import os
import sys
import re
import getpass
path = os.path.dirname(os.path.abspath(sys.argv[0]))


# 用于处理输入的数据格式
def cmd_format(lable, rule):
    while True:
        print('{} (<#q> exit):'.format(lable))
        if lable.strip().strip(':').upper() == 'PASSWORD':
            temp = getpass.getpass()
        else:
            temp = input().strip()
        content = re.match(r'{}'.format(rule), temp)
        if content:
            break
        elif 'port' in lable:
            temp = 22
            break
        elif temp.strip() == '#q':
            os.system('cls')
            break
        os.system('cls')
        print('[Warning]: Invalid format...')
    return temp


def about():
    f = open('{}/info/about.bat'.format(path))
    content = f.read()
    try:
        info = eval(content)
        os.system('cls')
        print('About SSH......')
        for k, v in info.items():
            print('{}: {}'.format(k, v))
    except:
        print('No Info......')
    f.close()
    return


# 添加主机信息
def add_host():
    print('Add host information......')
    print('[HELP]: INPUT <#q> exit...')
    # IP地址
    host_ip = cmd_format('Host IP:', '^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$')
    if host_ip == '#q':
        return True
    # 端口号
    host_port = cmd_format('Host port(Default 22):', '[0-9]+')
    if host_port == '#q':
        return True
    # 用户名
    username = cmd_format('User Name:', '^[^ ]+$')
    if username == '#q':
        return True
    # 密码
    password = cmd_format('Password:', '.*')
    if password == '#q':
        return True
    # password = base64.encodestring(password)
    # 输入别名
    alias = cmd_format('Local Alias:', '^[^ ]+$')
    if alias == '#q':
        return True
    elif not alias:
        os.system('cls')
        print('[Warning]: Alias cannot be empty...')
        return False
    # 查重
    f = open('{}/data/info.d'.format(path))
    hosts = f.readlines()
    for line in hosts:
        temp = line.strip('\n')
        if not temp:
            continue
        line_list = line.split(' ')
        if host_ip == line_list[0] and host_port == line_list[1]:
            os.system('cls')
            print('[Warning]: {}: {} existing...'.format(host_ip, host_port))
            return False
        if alias == line_list[4]:
            os.system('cls')
            print('[Warning]: Alias <{}> existing...'.format(alias))
            return False
    f.close()
    # 保存
    f = open('{}/data/info.d'.format(path), 'a')
    f.write('\n{} {} {} {} {}'.format(host_ip.strip('\n'), host_port, username.strip('\n'), password.strip('\n'), alias.strip('\n')))
    f.close()
    print('[INFO]:{} {}@{}:{} Add Successfully...'.format(alias.strip('\n'), username.strip('\n'), host_ip.strip('\n'), password.strip('\n')))
    return True


def add_hosts():
    while True:
        if add_host():
            break
        print('\n\nTry Again:')


# 删除主机信息
def remove_host():
    while True:
        f = open('{}/data/info.d'.format(path))
        hosts = f.readlines()
        f.close()
        hosts_len = len(hosts)
        if hosts_len < 1:
            os.system('cls')
            print('[Warning]: No host info...')
            return
        print('Remove host information......')
        print('%' * 40)
        print('FORMAT:\nAlias UserName@IP: PORT')
        print('%' * 40)
        hosts_temp = []
        n = 1
        for i in range(0, hosts_len):
            if not hosts[i].strip():
                continue
            line_list = hosts[i].strip().split(' ')
            print("<{}>: {} |{}@{}: {}|".format(n, line_list[4], line_list[2], line_list[0], line_list[1]))
            n += 1
            hosts_temp.append(hosts[I])
        hosts = hosts_temp[:]
        choice = input('[Remove]: Choose the Number or Alias(<#q> to exit):')
        is_alias = False
        is_num = False
        try:
            choice = int(choice)
            if choice < 1 or choice > hosts_len:
                os.system('cls')
                print('[Warning]:Number inexistence...')
                continue
            del hosts[choice-1]
            is_num = True
        except:
            is_alias = True
        if is_alias:
            if choice.strip() == '#q':
                os.system('cls')
                break
            n = 0
            for h in hosts:
                if choice.strip() == h.split(' ')[4].strip():
                    del hosts[n]
                    is_num = True
                n += 1
        if not is_num:
            os.system('cls')
            print('[Warning]:Alias inexistence...')
            continue
        else:
            choice = input('Remove?[y/n]:')
            if choice.strip().upper() == 'Y':
                f = open("{}/data/info.d".format(path), "w")
                for h in hosts:
                    f.write(h)
                print('Remove Successfully...')
                f.close()

文章到这里就结束了,感谢你的观看,关注我每天分享Python小工具系列,下篇文章分享简易的计时器

为了感谢读者们,我想把我最近收藏的一些编程干货分享给大家,回馈每一个读者,希望能帮到你们。

点击干货主要有获取

① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

⑥ 两天的Python爬虫训练营直播权限

All done~完整源代码+干货详见个人简介或者私信获取。