天天看点

Python[8] :paramiko模块多进程批量管理主机

一、paramiko简介

paramiko是用Python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。

paramiko主要是通过ssh协议对远程主机进行管理:包括执行远程主机CLI、上传和下载文件等。

二、快速安装paramiko模块

1

2

<code># yum install python-devel</code>

<code># pip install paramiko</code>

三、paramiko命令参数详解

利用密码登陆方式批量执行命令

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<code>导入模块</code>

<code>import</code> <code>paramiko</code>

<code>实例化一个SSHClient对象</code>

<code>s </code><code>=</code> <code>paramiko.SSHClient()</code>

<code>自动添加策略  </code><code>#首次登陆用交互式确定(允许连接不在know_hosts文件中的主机)</code>

<code>s.set_missing_host_key_policy(paramiko.AutoAddPolicy())</code>

<code>要连接的主机地址信息</code>

<code>s.connect(hostname</code><code>=</code><code>'ip地址'</code><code>, port</code><code>=</code><code>端口号, username</code><code>=</code><code>'用户名'</code><code>, password</code><code>=</code><code>'密码'</code><code>)</code>

<code>要执行的命令</code>

<code>stdin, stdout, stderr </code><code>=</code> <code>s.exec_command(</code><code>'执行的命令'</code><code>)</code>

<code>查看命令的执行结果</code>

<code>print</code> <code>stdout.read()</code>

利用公钥验证方式批量执行命令

18

19

20

21

22

23

24

25

26

<code>首先建立公钥和私钥文件</code>

<code># ssh-keygen</code>

<code>    </code> 

<code>上传本地的公钥到远程主机的.ssh</code><code>/</code><code>authorized_keys文件中</code>

<code># ssh-copy-id -i .ssh/id_rsa.pub root@ip</code>

<code>实例化一个对象</code>

<code>自动添加策略  </code><code>#首次登陆用交互式确定</code>

<code>建立私钥文件连接</code>

<code>key </code><code>=</code> <code>paramiko.RSAKey.from_private_key_file(</code><code>'/root/.ssh/id_rsa'</code><code>)</code>

<code>通过私钥验证的方式登录远程主机</code>

<code>s.connect(hostname</code><code>=</code><code>'ip地址'</code><code>, port</code><code>=</code><code>端口号, username</code><code>=</code><code>'用户名'</code><code>, pkey</code><code>=</code><code>key)</code>

<code>print</code> <code>stdout.read()</code>

从远程主机上传、下载文件

<code>#建立一个加密的传输管道</code>

<code>s </code><code>=</code> <code>paramiko.Transport((</code><code>'ip地址'</code><code>,端口号))</code>

<code>#建立连接</code>

<code>s.connect(username</code><code>=</code><code>'用户名'</code><code>,password</code><code>=</code><code>'密码'</code><code>)</code>

<code>#建立一个sftp客户端对象,通过ssh transport操作远程文件</code>

<code>sftp </code><code>=</code> <code>paramiko.SFTPClient.from_transport(s)</code>

<code>#上传本地文件到远程主机</code>

<code>sftp.put(localFile,remoteFile)</code>

<code>#从远程主机下载文件到本地</code>

<code>sftp.get(remoteFile,localFile)</code>

<code>#关闭sftp连接</code>

<code>s.close()</code>

四、脚本演示

局域网物理主机批量管理:执行命令

脚本还有很多瑕疵,只是作为参考练习,前提是所有主机的用户名、密码和端口号都要相同

例如:Username:root    Password:redhat     Port:22

27

28

29

30

31

32

33

34

35

<code>[root@python script]</code><code># cat 02_paramiko_process.py </code>

<code>#!/usr/bin/env python</code>

<code>#coding:utf8</code>

<code>from</code> <code>multiprocessing </code><code>import</code> <code>Process</code>

<code>import</code> <code>sys</code>

<code>Username </code><code>=</code> <code>'root'</code>

<code>Password </code><code>=</code> <code>'redhat'</code>

<code>Port </code><code>=</code> <code>22</code>

<code>def</code> <code>runCmd(ip,cmd):</code>

<code>    </code><code>s </code><code>=</code> <code>paramiko.SSHClient()</code>

<code>    </code><code>s.set_missing_host_key_policy(paramiko.AutoAddPolicy())</code>

<code>    </code><code>try</code><code>:</code>

<code>        </code><code>s.connect(hostname</code><code>=</code><code>ip, port</code><code>=</code><code>Port, username</code><code>=</code><code>Username, password</code><code>=</code><code>Password)</code>

<code>        </code><code>stdin, stdout, stderr </code><code>=</code> <code>s.exec_command(cmd)</code>

<code>        </code><code>result </code><code>=</code>  <code>stdout.read()</code>

<code>    </code><code>print</code> <code>ip,result,</code>

<code>    </code><code>except</code><code>:</code>

<code>    </code><code>print</code> <code>'%s is not exists'</code> <code>%</code> <code>ip</code>

<code>def</code> <code>ipProcess():</code>

<code>        </code><code>cmd </code><code>=</code> <code>sys.argv[</code><code>1</code><code>]</code>

<code>        </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>2</code><code>,</code><code>255</code><code>):</code>

<code>            </code><code>ip </code><code>=</code> <code>'192.168.1.%s'</code> <code>%</code> <code>i</code>

<code>        </code><code>p </code><code>=</code> <code>Process(target</code><code>=</code><code>runCmd,args</code><code>=</code><code>(ip,cmd))</code>

<code>            </code><code>p.start()</code>

<code>    </code><code>except</code> <code>IndexError:</code>

<code>        </code><code>print</code> <code>'please input a command.'</code>

<code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>'__main__'</code><code>:</code>

<code>    </code><code>ipProcess()</code>

执行脚本:

<code>[root@python script]</code><code># python 02_paramiko_process.py uptime</code>

截图部分返回结果:

<code>192.168</code><code>.</code><code>1.57</code>  <code>10</code><code>:</code><code>48</code><code>:</code><code>49</code> <code>up  </code><code>2</code><code>:</code><code>29</code><code>,  </code><code>0</code> <code>users,  load average: </code><code>0.00</code><code>, </code><code>0.00</code><code>, </code><code>0.00</code>

<code>192.168</code><code>.</code><code>1.56</code>  <code>10</code><code>:</code><code>50</code><code>:</code><code>25</code> <code>up  </code><code>2</code><code>:</code><code>29</code><code>,  </code><code>0</code> <code>users,  load average: </code><code>0.00</code><code>, </code><code>0.00</code><code>, </code><code>0.00</code>

<code>192.168</code><code>.</code><code>1.100</code>  <code>10</code><code>:</code><code>48</code><code>:</code><code>50</code> <code>up  </code><code>2</code><code>:</code><code>29</code><code>,  </code><code>0</code> <code>users,  load average: </code><code>0.00</code><code>, </code><code>0.00</code><code>, </code><code>0.00</code>

<code>192.168</code><code>.</code><code>1.127</code> <code>is</code> <code>not</code> <code>exists</code>

<code>192.168</code><code>.</code><code>1.210</code>  <code>22</code><code>:</code><code>48</code><code>:</code><code>51</code> <code>up  </code><code>2</code><code>:</code><code>28</code><code>,  </code><code>0</code> <code>users,  load average: </code><code>0.00</code><code>, </code><code>0.00</code><code>, </code><code>0.00</code>

<code>192.168</code><code>.</code><code>1.51</code>  <code>10</code><code>:</code><code>48</code><code>:</code><code>52</code> <code>up  </code><code>2</code><code>:</code><code>28</code><code>,  </code><code>0</code> <code>users,  load average: </code><code>0.00</code><code>, </code><code>0.00</code><code>, </code><code>0.00</code>

<code>192.168</code><code>.</code><code>1.55</code>  <code>10</code><code>:</code><code>50</code><code>:</code><code>26</code> <code>up  </code><code>2</code><code>:</code><code>29</code><code>,  </code><code>0</code> <code>users,  load average: </code><code>0.00</code><code>, </code><code>0.00</code><code>, </code><code>0.00</code>

<code>192.168</code><code>.</code><code>1.122</code> <code>is</code> <code>not</code> <code>exists</code>

<code>192.168</code><code>.</code><code>1.58</code> <code>is</code> <code>not</code> <code>exists</code>

<code>192.168</code><code>.</code><code>1.52</code> <code>is</code> <code>not</code> <code>exists</code>

<code>192.168</code><code>.</code><code>1.53</code> <code>is</code> <code>not</code> <code>exists</code>

<code>192.168</code><code>.</code><code>1.50</code> <code>is</code> <code>not</code> <code>exists</code>

<code>192.168</code><code>.</code><code>1.215</code>  <code>02</code><code>:</code><code>31</code><code>:</code><code>14</code> <code>up  </code><code>2</code><code>:</code><code>07</code><code>,  </code><code>4</code> <code>users,  load average: </code><code>4.75</code><code>, </code><code>1.46</code><code>, </code><code>0.82</code>

局域网物理主机批量管理:执行上传、下载文件

这里只对批量上传做了演示,对于批量下载文件只是一行代码的更换就可以了,我也在脚本中添加了注释行。

<code>[root@python script]</code><code># cat 03_put_paramiko_process.py </code>

<code>def</code> <code>sftpPut(ip):</code>

<code>        </code><code>s </code><code>=</code> <code>paramiko.Transport((ip,Port))</code>

<code>        </code><code>s.connect(username</code><code>=</code><code>Username,password</code><code>=</code><code>Password)</code>

<code>        </code><code>sftp </code><code>=</code> <code>paramiko.SFTPClient.from_transport(s)</code>

<code>        </code><code>localFile </code><code>=</code> <code>'/root/sync.sh'</code>

<code>        </code><code>remoteFile </code><code>=</code> <code>'/opt/sync.sh'</code>

<code>        </code><code>sftp.put(localFile,remoteFile)</code>

<code>        </code><code>#sftp.get(remoteFile,localFile)</code>

<code>        </code><code>s.close()</code>

<code>    </code><code>print</code> <code>'%s put successful.'</code> <code>%</code> <code>ip</code>

<code>    </code><code>print</code> <code>'%s not exists.'</code> <code>%</code> <code>ip</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>2</code><code>,</code><code>255</code><code>):</code>

<code>        </code><code>ip </code><code>=</code> <code>'192.168.1.%s'</code> <code>%</code> <code>i</code>

<code>        </code><code>p </code><code>=</code> <code>Process(target</code><code>=</code><code>sftpPut,args</code><code>=</code><code>(ip,))</code>

<code>        </code><code>p.start()</code>

<code>[root@python script]</code><code># python 03_put_paramiko_process.py</code>

<code>192.168</code><code>.</code><code>1.55</code> <code>put successful.</code>

<code>192.168</code><code>.</code><code>1.181</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.198</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.200</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.207</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.209</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.57</code> <code>put successful.</code>

<code>192.168</code><code>.</code><code>1.51</code> <code>put successful.</code>

<code>192.168</code><code>.</code><code>1.56</code> <code>put successful.</code>

<code>192.168</code><code>.</code><code>1.233</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.127</code> <code>not</code> <code>exists.</code>

<code>192.168</code><code>.</code><code>1.100</code> <code>put successful.</code>

<code>192.168</code><code>.</code><code>1.210</code> <code>put successful.</code>

登陆远程主机查看文件是否上传完成:

<code>[root@python script]</code><code># ssh 192.168.1.51</code>

<code>Address </code><code>192.168</code><code>.</code><code>1.51</code> <code>maps to localhost, but this does </code><code>not</code> <code>map</code> <code>back to the address </code><code>-</code> <code>POSSIBLE BREAK</code><code>-</code><code>IN ATTEMPT!</code>

<code>root@</code><code>192.168</code><code>.</code><code>1.51</code><code>'s password: </code>

<code>Last login: Wed Mar </code><code>11</code> <code>11</code><code>:</code><code>04</code><code>:</code><code>30</code> <code>2015</code> <code>from</code> <code>192.168</code><code>.</code><code>1.112</code>

<code>[root@naginx ~]</code><code># ifconfig |grep inet |head -1</code>

<code>          </code><code>inet addr:</code><code>192.168</code><code>.</code><code>1.51</code>  <code>Bcast:</code><code>192.168</code><code>.</code><code>1.255</code>  <code>Mask:</code><code>255.255</code><code>.</code><code>255.0</code>

<code>[root@naginx ~]</code><code># ll /opt/sync.sh -d</code>

<code>-</code><code>rw</code><code>-</code><code>r</code><code>-</code><code>-</code><code>r</code><code>-</code><code>-</code> <code>1</code> <code>root root </code><code>333</code> <code>3</code><code>月  </code><code>11</code> <code>11</code><code>:</code><code>05</code> <code>/</code><code>opt</code><code>/</code><code>sync.sh    </code><code>#已经成功上传文件</code>

注意:

批量上传文件脚本只能满足单个文件,如何实现多个文件上传和下载呢?可以通过os模块来实现,下一篇文章中介绍如何以更人性化的方式实现参数上传下载,那就是os模块和optparse模块

     本文转自zys467754239 51CTO博客,原文链接:http://blog.51cto.com/467754239/1619166,如需转载请自行联系原作者