楼主python小白一枚,无任何编程经验。近期研究python自动化运维技术与最佳实践,今天在看paramiko模块,依葫芦画瓢,实现了两个小程序,分享如下!
首先,简单介绍下paramiko这个模块。paramiko是基于python实现的SSH2远程安全连接、支持认证及密钥方式,实现远程命令执行,文件传输,中间ssh代理等,相对Pexpect,封装的层次更高,更贴近SSH协议的功能。
安装的话,采用pip安装即可,指令很简单:pip install paramiko
当然,前提需要配置好pip。
废话不多说,上代码:
1、示例1:
该代码读取当前目录下commands.txt(该文件记录需要执行的命令)文件的内容,并进行处理,返回命令行列表,然后在main()函数中直接调用paramiko模块相关方法,顺次执行文件中的命令,并打印出输出结果。
[root@cenos paramiko]# more simple1.py
#!/usr/bin/pythonimport sys
import osimport paramikodef get_cmds(fp='commands.txt'):
if os.path.isfile(fp) and os.access(fp,os.R_OK): f = open(fp,'rb') lines = f.readlines() f.close()cmds = map(lambda x:x.rstrip(),lines)
return cmdselse:
sys.exit() return None def main(): if len(sys.argv) == 4: host = sys.argv[1] user = sys.argv[2] passwd = sys.argv[3] else: print "Usage:%s host user passwd"%(sys.argv[0]) sys.exit() paramiko.util.log_to_file('syslogin.log') ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=host,username=user,password = passwd) cmds = get_cmds() for cmd in cmds: stdin,stdout,stderr = ssh.exec_command(cmd) print stdout.read()ssh.close()
if __name__ == "__main__": main()在该示例中,commands.txt文件的内容如下(可以根据自己实际需要将命令写入这个文件即可,无需修改原始代码):
[root@cenos paramiko]# more commands.txt
free -muptimeuname -adf -hwho指令结果如下:
[root@cenos paramiko]# ./simple1.py Usage:./simple1.py host user passwd #远程server的主机名,用户名,密码通过命令行参数输入,此处未给定,直接输出了用法提示。
[root@cenos paramiko]# ./simple1.py 192.168.0.200 root 123456 total used free shared buff/cache availableMem: 984 96 733 6 154 728Swap: 3967 0 396718:33:17 up 1 day, 4:38, 1 user, load average: 0.00, 0.01, 0.05
Linux admin-node 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/cl-root 36G 1.4G 34G 4% /devtmpfs 482M 0 482M 0% /devtmpfs 493M 0 493M 0% /dev/shmtmpfs 493M 6.8M 486M 2% /runtmpfs 493M 0 493M 0% /sys/fs/cgroup/dev/sda1 1014M 139M 876M 14% /boottmpfs 99M 0 99M 0% /run/user/0root tty1 2017-10-16 09:09
该例子比较简单,如果需要在多台服务器上同时执行指令,可以把远程主机信息通过字典的格式存入列表,通过循环顺次执行。此处不再赘述,楼主自己也没有码相关的代码。
2、示例2:
该代码首先筛选出给定目录下(含子目录)后缀为.py的所有文件,并将文件名称存入列表;然后通过tar_files函数将文件打包,最后通过put_files函数将打包文件上传到远端服务器,而put_files函数使用了paramiko的put方法。
[root@cenos paramiko]# more simple2.py
#!/usr/bin/pythonimport sys
import osimport tarfileimport datetimeimport paramiko def get_files(dir_path,files=[]): for name in os.listdir(dir_path): full_path = os.path.join(dir_path,name) if os.path.isfile(full_path) and os.path.splitext(full_path)[1]=='.py': files.append(full_path)if os.path.isdir(full_path):
get_files(full_path,files)return files
def tar_files(files,dst):
if isinstance(files,list): tar = tarfile.open(dst,'w:gz') for file in files: tar.add(file) tar.close()else:
sys.exit() def put_files(host,user,passwd,localpath,remotepath): tran = paramiko.Transport((host,22)) tran.connect(username=user,password=passwd) sftp = paramiko.SFTPClient.from_transport(tran) sftp.put(localpath,remotepath) tran.close() def main(): try: files = get_files('/root/python') suffix = datetime.datetime.now().strftime("%Y%m%d%H%M") dst = "/tmp/tar_%s.tar.gz"%(suffix) tar_files(files,dst) remotepath = dst put_files('192.168.0.200','root','123456',dst,remotepath)except Exception,e:
print str(e) sys.exit()if __name__ == "__main__":
main()执行该脚本:
[root@cenos paramiko]# ./simple2.py
本端主机上的压缩文件
[root@cenos tmp]# pwd
/tmp[root@cenos tmp]# ls -al *.tar.gz-rw-r--r-- 1 root root 56884 Oct 20 17:55 tar_201710201755.tar.gz-rw-r--r-- 1 root root 56884 Oct 20 18:41 tar_201710201841.tar.gz-r--r--r--. 1 root root 60654199 Sep 25 2016 VMwareTools-9.6.0-1294478.tar.gz远端主机上的压缩文件:
[root@admin-node ~]# cd /tmp
[root@admin-node tmp]# ls -al *.tar.gz-rw-r--r-- 1 root root 27179 Oct 16 11:40 tar_201710161140.tar.gz-rw-r--r-- 1 root root 27179 Oct 16 12:14 tar_201710161214.tar.gz-rw-r--r-- 1 root root 56884 Oct 20 17:55 tar_201710201755.tar.gz-rw-r--r-- 1 root root 56884 Oct 20 18:41 tar_201710201841.tar.gz完美实现文件的压缩和上传,哈哈!
今天仅仅学习了paramiko的SSHClient和SFTPClient两个类,也仅仅了解了最基本的使用方法,后续再学习,再更新,与各位共勉!