背景
从前有一位Linux运维大哥经常对着一台一台服务器敲着重复的命令!这位大哥的ctrlCV操作了得!alt tab出神入化!但此时,一句句声音在他耳边环绕,“对不起,你不行,手指头要抽筋了!放弃吧!”这时的大哥即恐慌又害怕,对天大喊:神阿,到底什么可以解救我!神回答:神也不知道,去问你妈。大哥又问,妈,到底什么可以解救我?妈回答:你去问神吧。最终大哥临近崩溃!崩溃之前打开csdn!看到了发亮的屏幕,一片名为《Python搞定繁琐运维之批量执行Linux命令》的文章映入你的眼帘。。。
(以上故事纯属编造,如有雷同,纯属巧合。但是道理还是那么个道理哈)
一、思路
要实现执行Linux命令其实步骤很简单,首先是要连接上服务器,然后对服务器进行操作,批量执行命令,那么就批量连接服务器,让服务器执行同一条命令即可。
二、实现
在代码实现之前先介绍Python的一个模块,paramiko模块,它实现了SSHv2协议。有了Paramiko以后,就可以在Python代码中直接使用SSH协议对远程服务器执行操作,而不是通过ssh命令对远程服务器进行操作。
paramiko模块主要有两大类(功能):SSHClient与SFTPClient。具体介绍与学习请移步官方文档。http://www.paramiko.org/
1.连接Linux(该连接方式是,以用户名和密码进行认证,如果服务器是用密钥进行认证,可以查阅官方文档进行代码修改)
import paramiko
client = paramiko.SSHClient() #创建连接对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy) #设置自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
try:
client.connect(hostname='192.168.254.128',port=22,username='root',password='999999') #connetc为连接函数
print('主机连接成功!')
except:
print('主机连接失败,请确认输入信息!')
只要信息填对一般都会连接成功。
2.让主机执行命令
import paramiko
client = paramiko.SSHClient() #创建连接对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy) #设置自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
try:
client.connect(hostname='192.168.254.128',port=22,username='root',password='999999') #connetc为连接函数
print('主机连接成功!')
except:
print('主机连接失败,请确认输入信息!')
stdin,stdout,stderr = client.exec_command('ifconfig') #stdout为指令正确信息,stderr为指令异常信息
print(stdout.read().decode('utf-8'))
print(stderr.read().decode('utf-8'))
输出:
3.现在连接上主机并且可以让主机执行命令了,但这样似乎不符合常理,执行一次就退出程序了?我们来改一改,让整个程序连接主机,并且可以一直输入指令执行指令。
import paramiko
def SSHLinux(ip,port,username,password):
client = paramiko.SSHClient() #创建连接对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy) #设置自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
try:
client.connect(hostname=ip,port=port,username=username,password=password) #connetc为连接函数
print(f'主机{ip}连接成功!')
except:
print(f'主机{ip}连接失败,请确认输入信息!')
main()
while True: 用无限循环来一直输入命令让服务器执行
e = input('请输入命令:')
stdin,stdout,stderr = client.exec_command(e) #stdout为指令正确信息,stderr为指令异常信息
print(stdout.read().decode('utf-8'))
print(stderr.read().decode('utf-8'))
print('-----------------------------------------------------------------------------------')
if (e=='eexit'): #当命令为eexit时退出连接循环结束程序
client.close()
print('已退出SSH连接')
break
def main(): #主方法
a = input('输入ip地址:')
b = input('输入SSH端口:')
c = input('输入用户名:')
d = input('输入密码:')
SSHLinux(a,b,c,d)
if __name__ == '__main__': #程序运行入口
main()
效果:
4.到此为止,一个像样的远程SSH执行命令工具就成形了,但是我们的目的是进行批量操作啊!所以,我们需要定义多个连接,输入多个主机信息,来完成批量操作。
import paramiko
def SSHLinux(ip,port,username,password,num): #程序SSH连接函数,也是本程序核心方法
a=[]
b=[]
c=[]
d=[]
for i in range(num):
a.append('client' + str(i))
b.append('stdin' + str(i))
c.append('stdout' + str(i))
d.append('stderr' + str(i))
a[i] = paramiko.SSHClient() #创建num个连接对象
# client2 = paramiko.SSHClient()
a[i].set_missing_host_key_policy(paramiko.AutoAddPolicy) #添加num个主机名及主机密钥到本地HostKeys对象
# client2.set_missing_host_key_policy(paramiko.AutoAddPolicy)
try:
a[i].connect(hostname=ip[i],port=port[i],username=username[i],password=password[i]) #num个连接
# client2.connect(hostname=ip[1],port=port[1],username=username[1],password=password[1])
print(f'主机{ip[i]}连接成功!')
except:
print(f'主机{ip[i]}连接失败,请确认输入信息!')
exit()
while True:
e = input('请输入命令:')
for i in range(num):
b[i],c[i],d[i] = a[i].exec_command(e) #num个对象执行e命令
# b[1],c[1],d[1] = a[1].exec_command(e)
# stdin1,stdout1,stderr1 = client2.exec_command(e)
print(f'----------------------{ip[i]}信息----------------------')
print(c[i].read().decode('utf-8')) #打印正确输出
print(d[i].read().decode('utf-8')) #打印错误输出
# print(f'----------------------{ip[1]}信息----------------------')
# print(c[1].read().decode('utf-8'))
# print(c[1].read().decode('utf-8'))
if (e=='eexit'):
a[i].close()
# a[1].close()
print('已退出SSH连接')
break
def main(): #主方法(运行函数),可以把批量ip端口账号密码对应的写入列表,然后把输入删掉运行
ip=[]
port=[]
username=[]
password = []
num = int(input('输入要进行SSH连接主机个数:'))
num2 = num
while num > 0:
a = input('输入ip:')
ip.append(a)
b = input('输入端口:')
port.append(b)
c = input('输入用户名:')
username.append(c)
d = input('输入密码:')
password.append(d)
num = num - 1
SSHLinux(ip,port,username,password,num2)
if __name__ == '__main__': #程序运行入口
main()
效果图:
结束
Python搞定繁琐运维之批量执行Linux命令到此结束!如果本文写的那里有不好的地方,或者有新的建议,恳请指出。
(接背景小故事:
运维大哥逐渐露出满意的笑容,并且运用的这个方法,从此搞定繁琐工作!)