python 之多主机批量执行命令

当每台linux主机需要做同样操作的时候,你还是一台一台ssh连上去吗,程序帮你批量操作。

当我们有很多台linux服务器的时候,而每台服务器都需要做同一个操作,比如很多节点的集群环境下,要更改一个配置文件,哪怕只是一行,在传统情况下,也需要每台去单独操作。

最近也是有这样的需求,需要操作的机器特别多,所以就写了一个小的程序

看到这里,可能有同学说了,我做了 ssh 免密码登录,可以用shell写个循环也能实现啊。可是当你做ssh的时候,不也是一台一台的操作吗?

其实用 shell 也可以做,并且shell 没有依赖,只不是你要提前把 ssh 免密码登录做好。

而使用 shell 若不做免密码,循环的时候,要输入每台的密码,我曾经在网上搜索过,好像没有什么方法可以把这个交互式做成自动化。

言归正传,本次使用 python ,并且使用 python 的 paramiko 模块,来操作。

paramiko 模块需要 gcc , openssl , pycrypto 等依赖,下面就来安装它。

## debian & ubuntu 平台
apt-get update
apt-get install gcc g++ openssl libssl-dev python-dev python-pip libffi-dev

## centos redhat 等平台,需要先安装 epel 第三方仓库
yum install epel-release

##之后再安装
yum install gcc gcc-c++ openssl openssl-devel python-devel python-pip libffi-devel

并且 paramiko 至少需要 python 2.7 以上的版本才支持。如果你 python 低于这个版本,请自行升级

依赖安装完以后,把 pip 升级到最新版本

pip install --upgrade pip

安装 paramiko

pip install pycrypto
pip install paramiko

请注意,pip 需要root权限,过程若有报错,请看详细情况,一般是上面的依赖没有安装好

目前已经将代码写成命令行操作了,下面直接上代码,然后再说用法

#!/usr/bin/python
# -- coding: utf-8 --

import paramiko
from optparse import OptionParser
from sys import argv


def ssh2(ip, port, username, password, cmd):
    for hosts in ip:
        try:
            paramiko.util.log_to_file('paramiko__.log')
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(hosts, port, username, password, timeout=7)
            stdin, stdout, stderr = ssh.exec_command(cmd)
            cmd_result = stdout.read(), stderr.read()
            print '%s --> command has been submitted, results are as follows.' % (hosts)
            for o in cmd_result:
                print o,
            ssh.close()
            print "\n"
        except Exception, msg:
            print hosts, msg


if __name__ == '__main__':

    parser = OptionParser()
    parser.add_option("--ip",
                      dest="ipaddr",
                      help="target host ip address"
                      )
    parser.add_option("--ipfile",
                      dest="ipfile",
                      help="ip list file"
                      )
    parser.add_option("--port",
                      dest="port",
                      help="ssh port number"
                      )
    parser.add_option("--username",
                      dest="username",
                      help="ssh user name"
                      )
    parser.add_option("--password",
                      dest="password",
                      help="ssh password"
                      )
    parser.add_option("--cmd",
                      dest="cmd",
                      help="Commands to execute"
                      )

    (options, args) = parser.parse_args()
    if "--ip" in argv and "--ipfile" in argv:
        print "Accept only one argument, use  --ip or --ipfile"
        exit(1)
    if options.ipaddr == None:
        ip_list = open(options.ipfile, "r")
        ip = ip_list.read().split("\n")[:-1]
        ip_list.close()

    if options.ipfile == None:
        ip_list = options.ipaddr
        ip = ip_list.split(",")

    cmd = options.cmd
    port = int(options.port)
    username = options.username
    password = options.password

    ssh2(ip, port, username, password, cmd)

将代码保存到一个文件,之后执行 python 文件名 -h ,即可以查看帮助,run_cmd.py 是我保存的名字,如下:

root@ainy:~# python run_cmd.py -h
Usage: run_cmd [options]
Options:
  -h, --help           show this help message and exit
  --ip=IPADDR          target host ip address
  --ipfile=IPFILE      ip list file
  --port=PORT          ssh port number
  --username=USERNAME  ssh user name
  --password=PASSWORD  ssh password
  --cmd=CMD            Commands to execute
root@ainy:~#

-h 查看帮助信息
–help 查看帮助信息
–ip 指定目标主机的IP地址,多个IP地址时,请使用英文状态的逗号分隔
–ipfile ip地址列表文件,可以把IP地址写一个文件里面,一行一个
–port ssh 端口号
–username ssh账号
–password ssh密码
–cmd 需要执行的命令,命令中包含空格,请使用双引号引起来

PS: –ip 参数 和 –ipfile 参数,您必须指定其中一个,程序也只接受一个

示例:

# 单个主机
python run_cmd.py --ip 192.168.1.22 --port 22 --username root --password 123456 --cmd "ls -l"

# 多个主机
python run_cmd.py --ip 192.168.7.19,192.168.7.20,192.168.10.177,192.168.73.145 --port 22 --username root --password 123456 --cmd "ls -l"

# 使用IP地址列表文件
python run_cmd.py --ipfile /root/kvmip.txt --port 22 --username root --password 123456 --cmd "ls -l"

IP 地址列表文件,请使用纯文件文件,并把换行符设置为 unix\linux 格式,否则会出错。

在windows 操作系统上,请不使用 记事本来创建 IP 列表文件,因为其换行符和 linux 不同,windows上您可以使用任何一款代表编辑器,上面可以转换换行符格式

在 linux 系统,您也可以直接使用 vim 等编辑器工具来创建IP列表文件。其换行符默认即是 unix\linux 格式

猜您喜欢