虽然目前都实现了自动化如puppet saltstack在环境中的应用,但工作中不可避免的要自己写一些简单的批量执行shell命令的脚本。
python paramiko模块是目前使用得较为顺手的模块,执行命令时基本无需要转换,直接将shell命令扔进去执行就OK
简单示例,10个线程同时执行ssh或scp动作,未设置timeout时间,如执行长时间无反应会导致脚本执行问题:
#!/usr/bin/python
# _*_ coding: utf-8 _*_
import paramiko
import sys
import logging
from multiprocessing.dummy import Pool as ThreadPool
import re
import os
try:
fun_name = sys.argv[1]
file = open(sys.argv[2])
except Exception,e:
print """use like:
#copy dir or file
shell_exec_map.py scp ip_file source_file des_file
#do cmd in host
exec_map.py ssh ip_file 'yum install -y zabbix'
"""
exit()
logging.basicConfig(level=logging.DEBUG ,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='exec_map.log',
filemode='a+')
#ssh key文件位置
privatekeyfile = os.path.expanduser('/root/.ssh/id_rsa')
mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile)
#############################
#对ssh key设置密码方式
#privatekeyfile = os.path.expanduser('/root/.ssh/id_rsa')
#mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile,password='password')
#############################
def getCmdInfo(host_ip,cmd):
print host_ip
try:
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
##################
#密码登录方式
#c.connect(host_ip,22,'root',password)
##################
c.connect(host_ip,22,'root',pkey=mykey)
stdin,stdout,stderr = c.exec_command(cmd)
info = stdout.read()
c.close()
return info
except Exception as e:
logging.error( 'getCmdInfo ip %s %s error: %s' % (host_ip,cmd,e))
def postFileToRemote(host_ip,localpath,remotepath):
print host_ip
try:
t = paramiko.Transport((host_ip,22))
##################
#密码登录方式
#t.connect(username='root',password='')
##################
t.connect(username='root',pkey=mykey)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put(localpath,remotepath)
sftp.close()
t.close()
except Exception,e:
logging.error( 'scp_cmd ip %s soure:%s des: %s error: %s' % (host_ip,localpath,remotepath,e))
#10个并发同时进行
pool = ThreadPool(10)
line_list = []
for line in file.readlines():
line_list.append(line.strip())
if fun_name == 'scp':
try:
pool.map(scpFile,line_list)
logging.debug('scpFile ip file %s source %s dec %s' % (sys.argv[2],sys.argv[3],sys.argv[4]))
except Exception as e:
logging.error( 'scpFile map error: %s ' % e)
elif fun_name == 'ssh':
try:
if pattern_cmd.findall(sys.argv[3]):
print "can't use rm command!"
logging.debug('sshCmd ip file %s cmd %s' % (sys.argv[2],sys.argv[3]))
else:
pool.map(sshCmd,line_list)
logging.debug('sshCmd ip file %s cmd %s' % (sys.argv[2],sys.argv[3]))
except Exception as e:
logging.error( 'sshCmd map error: %s ' % e)
pool.close()
pool.join()
ansible基于paramiko模块做的批量执行脚本,远端执行
1、安装ansible软件,配置了epel源,或者线上下载ansible-1.7.2
2、配置节点,IP(主机名需要主机能正常解析)
vi /etc/ansible/hosts
[other]
zabbix-127023.xxx.com
haproxy-127021.xxx .com
controller-127022.xxx .com
haproxy-127021.xxx.com
3、执行Ping命令测试(带上环境变量. ~/.bash_profile)
ansible -m shell -a '. ~/.bash_profile &&ping -c 2 10.197.128.1' other
controller-129022.xxx.com | success | rc=0 >>
PING 10.197.128.1 (10.198.127.1) 56(84) bytes of data.
64 bytes from 10.198.127.1: icmp_seq=1 ttl=254 time=0.466 ms
64 bytes from 10.198.127.1: icmp_seq=2 ttl=254 time=0.409 ms
--- 10.198.127.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.409/0.437/0.466/0.035 ms
pinsh-127024.xxx.com | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
ansible方法有个不方便的地方第一次执行时,需要手动确认下。python脚本不需要手动确认