博客是我工作的好帮手,遇到困难就来博客找资料
分类: 系统运维
2020-09-09 10:40:35
pip install paramiko
可以修改ssh连接超时时间,windows下路径:在安装路径Python\Python36\Lib\site-packages\paramiko\transport.py,修改self.banner_timeout = 60(设置ssh超时为60秒)
import paramiko,getpass #getpass是隐藏密码 def ssh_connect(password):
host_ip = '192.168.0.150' user_name = 'root' host_port ='22' # 待执行的命令 sed_command = "sed -i 's/123/abc/g' /root/test/test.txt" ls_command = "ls /root/test/" # 注意:依次执行多条命令时,命令之间用分号隔开 command = sed_command+";"+ls_command # SSH远程连接 ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存下本机的秘钥 ssh.connect(host_ip, host_port, user_name, password) # 执行命令并获取执行结果 stdin, stdout, stderr = ssh.exec_command(command)
out = stdout.readlines()
err = stderr.readlines() #关闭连接 ssh.close() return out,err if __name__ == '__main__':
pwd = getpass.getpass("请输入密码:")
#有了密码,开始调用函数 result = ssh_connect(pwd) print(result)
python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件。
1、得到一个连接的对象
在进行连接的时候,可以使用如下的代码:
def connect(host): ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: #ssh.connect(host,username='root',allow_agent=True,look_for_keys=True) ssh.connect(host,username='root',password='root',allow_agent=True) return ssh except: return None
在connect函数中,参数是一个主机的IP地址或者是主机名称,在执行这个方法之后,如果成功的连接到服务器,那么就会返回一个sshclient对象。
第一步是建立一个SSHClient的对象,然后设置ssh客户端允许连接不在know_host文件中的机器,然后就尝试连接服务器。
在连接服务器的时候,可以使用两种方式:
(1)方式是使用秘钥的方式,也就是参数look_for_keys
(2)用设置密码寻找,也可以直接使用密码的方式,也就是直接使用参数password,从而最后返回一个连接的对象。
2、 获取设置的命令
在进行paramiko连接之后,那么必须要得到需要执行的命令,如下代码所示:
def command(args,outpath): cmd = '%s %s' % (outpath,args) return cmd
在参数中,一个是args,一个outpath,args表示命令的参数,而outpath表示为可执行文件的路径,例如/usr/bin/ls -l。在其中outpath也就是/usr/bin/ls ,而参数为-l
这个方法主要是用来组合命令,将分开的参数作为命令的一部分进行组装。
3、 执行命令
在连接过后,可以进行直接执行命令,那么就有了如下的函数:
def exec_commands(conn,cmd): stdin,stdout,stderr = conn.exec_command(cmd)
results=stdout.read() return results
在此函数中,传入的参数一个为连接的对象conn,一个为需要执行的命令cmd,最后得到执行的结果,也就是stdout.read(),最后返回得到的结果
4、 上传文件
在使用连接对象的时候,也可以直接进行上传相关的文件,如下函数:
def copy_moddule(conn,inpath,outpath): ftp = conn.open_sftp() ftp.put(inpath,outpath)
ftp.close() return outpath
此函数的主要参数为,一个是连接对象conn,一个是上传的文件名称,一个上传之后的文件名称,在此必须写入完整的文件名称包括路径。
做法主要是打开一个sftp对象,然后使用put方法进行上传文件,最后关闭sftp连接,最后返回一个上传的文件名称的完整路径
5、 执行命令得到结果
最后就是,执行命令,得到返回的结果,如下代码:
def excutor(host,outpath,args):
conn = connect(host) if not conn: return [host,None]
#调用函数
exec_commands(conn,'chmod +x %s' % outpath)
#调用函数,获得命令参数及其路径
cmd =command(args,outpath)
#调用函数执行命令
result = exec_commands(conn,cmd) print '%r' % result
result = json.loads(result) return [host,result]
首先,进行连接服务器,得到一个连接对象,如果连接不成功,那么返回主机名和None,表示没有连接成功,如果连接成功,那么修改文件的执行权限,从而可以执行文件,然后得到执行的命令,最后,进行执行命令,得到结果,将结果用json格式表示返回,从而结果能得到一个美观的json格式,最后和主机名一起返回相关的信息
6、 测试代码
测试代码如下:
if __name__ == '__main__': print json.dumps(excutor('192.168.1.165','ls',' -l'),indent=4,sort_keys=True) print copy_module(connect('192.168.1.165'),'kel.txt','/root/kel.1.txt')
exec_commands(connect('192.168.1.165'),'chmod +x %s' % '/root/kel.1.txt')
第一步测试命令执行,第二步测试上传文件,第三部测试修改上传文件的权限。
完整代码如下:
#!/usr/bin/env python import json import paramiko def connect(host): ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: #ssh.connect(host,username='root',allow_agent=True,look_for_keys=True) ssh.connect(host,username='root',password='root',allow_agent=True) return ssh except: return None def command(args,outpath): cmd = '%s %s' % (outpath,args) return cmd def exec_commands(conn,cmd): stdin,stdout,stderr = conn.exec_command(cmd)
results=stdout.read() return results def excutor(host,outpath,args):
conn = connect(host) if not conn: return [host,None] #exec_commands(conn,'chmod +x %s' % outpath) cmd =command(args,outpath)
result = exec_commands(conn,cmd)
result = json.dumps(result) return [host,result] def copy_module(conn,inpath,outpath):
ftp = conn.open_sftp()
ftp.put(inpath,outpath)
ftp.close()
return outpath if __name__ == '__main__':
print json.dumps(excutor('192.168.1.165','ls',' -l'),indent=4,sort_keys=True)
print copy_module(connect('192.168.1.165'),'kel.txt','/root/kel.1.txt')
exec_commands(connect('192.168.1.165'),'chmod +x %s' % '/root/kel.1.txt')
pexpect模块版本
#!/usr/bin/env python # -*- coding: utf-8 -*- import pexpect def ssh_cmd(ip, passwd, cmd):
ret = -1 ssh = pexpect.spawn('ssh root@%s "%s"' % (ip, cmd)) try:
i = ssh.expect(['password:', 'continue connecting (yes/no)?'], timeout=5) if i == 0 : ssh.sendline(passwd) elif i == 1:
ssh.sendline('yes\n') ssh.expect('password: ') ssh.sendline(passwd) ssh.sendline(cmd)
r = ssh.read() print r
ret = 0 except pexpect.EOF: print "EOF" ssh.close()
ret = -1 except pexpect.TIMEOUT: print "TIMEOUT" ssh.close() ret = -2 return ret
aramiko模块版本
#-*- coding: utf-8 -*- #!/usr/bin/python import paramiko import threading def ssh2(ip,username,passwd,cmd): try: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip,22,username,passwd,timeout=5) for m in cmd: stdin, stdout, stderr = ssh.exec_command(m) #stdin.write("Y") #简单交互,输入 ‘Y' out = stdout.readlines() #屏幕输出 for o in out: print o, print '%s\tOK\n'%(ip) ssh.close() except : print '%s\tError\n'%(ip) if __name__=='__main__': cmd = ['cal','echo hello!']#你要执行的命令列表 username = "" #用户名 passwd = "" #密码 threads = [] #多线程 print "Begin......" for i in range(1,254): ip = '192.168.1.'+str(i) #开启多线程执行命令 a=threading.Thread(target=ssh2,args=(ip,username,passwd,cmd)) a.start()
import paramiko
def create_user(root_pwd,username,password): result = []
ssh = paramiko.SSHClient() #把要连接的机器添加到known_hosts文件中 ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(
hostname = settings.HOST,
port = settings.PORT,
username = settings.USERNAME,
password = settings.PASSWORD,
timeout = 60,
)
sc = ssh.invoke_shell()
#定义函数 def exe_cmd(cmd,t=0.1):
sc.send(cmd)
sc.send("\n") time.sleep(t) resp = sc.recv(9999).decode("utf8") #print "cmd='%s',echo='%s'\n"%(cmd,resp) return resp #切换root账号 resp = exe_cmd("su root",t=1) if resp.endswith(u"密码:"):
resp = exe_cmd(root_pwd) #创建用户 cmd_create_user = "useradd {username} -d /home/{username}".format(
username = username,
)
exe_cmd(cmd_create_user) #修改密码 cmd_change_user_pwd = """echo "{password}" | passwd --stdin {username}""".format(
username = username,
password = password,
)
exe_cmd(cmd_change_user_pwd)
import paramiko def sshclient_execmd(hostname, port, username, password, execmd):
paramiko.util.log_to_file("paramiko.log") s = paramiko.SSHClient() s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接 s.connect(hostname=hostname, port=port, username=username, password=password)
#执行
stdin, stdout, stderr = s.exec_command (execmd)
stdin.write("Y") # Generally speaking, the first connection, need a simple interaction. print stdout.read() s.close() def main():
hostname = '10.***.***.**' port = 22 username = 'root' password = '******' execmd = "free" #调用函数
sshclient_execmd(hostname, port, username, password, execmd) if __name__ == "__main__":
main()
import paramiko #实例化ssh客户端 ssh = paramiko.SSHClient() #创建默认的白名单 policy = paramiko.AutoAddPolicy() #设置白名单 ssh.set_missing_host_key_policy(policy) #链接服务器 ssh.connect(
hostname = "192.168.2.186", #服务器的ip port = 22, #服务器的端口 username = "root", #服务器的用户名 password = "123" #用户名对应的密码 ) #远程执行命令 stdin,stdout,stderr = ssh.exec_command("ls") #exec_command 返回的对象都是类文件对象 #stdin 标准输入 用于向远程服务器提交参数,通常用write方法提交 #stdout 标准输出 服务器执行命令成功,返回的结果 通常用read方法查看 #stderr 标准错误 服务器执行命令错误返回的错误值 通常也用read方法 #查看结果,注意在Python3 字符串分为了:字符串和字节两种格式,文件返回的是字节 result = stdout.read().decode() print(result)
paramiko+threading 实现远程服务器批量执行命令
#coding:utf-8 import sys import paramiko import threading def getConnection(ip,username,password,command,port = 22): #实例化对象
ssh = paramiko.SSHClient()
policy = paramiko.AutoAddPolicy()
ssh.set_missing_host_key_policy(policy)
#连接 ssh.connect(
hostname = ip, # 服务器的ip port = port, # 服务器的端口 username = username, # 服务器的用户名 password = password # 用户名对应的密码 )
#执行
stdin, stdout, stderr = ssh.exec_command(command)
result = stdout.read().decode() error = stderr.read().decode() print("+++++++++++++++++++++++start++++++++++++++++++++") print("[connect success] | ip : %s" % ip) print("result: \n %s"%result) if error != " ": print("error: \n %s"%error) print("+++++++++++++++++++++++done++++++++++++++++++++") ssh.close() #我们采用多线程 def main(host_list,command):
thread_list = [] for ip,username,password in host_list: thread = threading.Thread(target = getConnection, args = (ip,username,password,command))
thread_list.append(thread) for t in thread_list:
t.start() for t in thread_list:
t.join() if __name__ == "__main__":
host_list = [
("192.168.2.186", "root", "123"),
("192.168.2.88", "root", "123"),
]
command = sys.argv[1] main(host_list,command)
#单线程运行 from time import sleep def loop(num,sleeptime): """ 当前函数作为功能函数
:param num: 函数的编号
:param sleeptime: 睡眠的时间 """ print("loop %s is start"%num)
sleep(sleeptime) print("loop %s is done"%num) def main():
sleep_list = [3,2] #睡眠时间 lenth = len(sleep_list) #获取列表长度 print("all is start") for i in range(lenth):
loop(i,sleep_list[i]) #按照列表长度和列表内容调用函数 print("all is down") if __name__ == "__main__":
main() #多线程运行 import threading from time import sleep def loop(num,sleeptime): """ 当前函数作为功能函数
:param num: 函数的编号
:param sleeptime: 睡眠的时间 """ print("loop %s is start"%num)
sleep(sleeptime) print("loop %s is done"%num) def main():
sleep_list = [3,2] #睡眠时间 lenth = len(sleep_list) #获取列表长度 thread_list = [] print("all is start") for i in range(lenth): #threading.Thread 就是用线程来执行我们的功能 t = threading.Thread(target = loop,args = (i,sleep_list[i])) #按照列表长度和列表内容调用函数 thread_list.append(t) #将生成的线程添加到列表里 for t in thread_list:
t.start() #开始执行线程 for t in thread_list:
t.join() #挂起线程,到所有线程结束 print("all is down")