一、Shell编程实战收集服务器信息
在企业上产环境中,经常会对服务器资产进行统计存档,单台服务器可以手动去统计服务器的CPU型号、内存大小、硬盘容量、网卡流量等,如果服务器数量超过百台、千台,使用手工方式就变得非常吃力。
基于Shell脚本实现自动化服务器硬件信息的收集,并将收集的内容存放在数据库,能更快、更高效的实现对服务器资产信息的管理。Shell脚本实现服务器信息自动收集,编写思路如下:
- 创建数据库和表存储服务器信息;
- 基于Shell四剑客awk、find、sed、grep获取服务器信息;
- q 将获取的信息写成SQL语句;
- q 定期对SQL数据进行备份;
- q 将脚本加入Crontab实现自动备份;
创建数据库表,创建SQL语句如下:
CREATE TABLE `audit_system` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ip_info` varchar(50) NOT NULL, `serv_info` varchar(50) NOT NULL, `cpu_info` varchar(50) NOT NULL, `disk_info` varchar(50) NOT NULL, `mem_info` varchar(50) NOT NULL, `load_info` varchar(50) NOT NULL, `mark_info` varchar(50) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ip_info` (`ip_info`), UNIQUE KEY `ip_info_2` (`ip_info`) );
Shell脚本实现服务器信息自动收集,代码如下:
#!/bin/bash #Auto get system info #By author jfedu.net 2017 #Define Path variables echo -e "\033[34m \033[1m" cat <<EOF ++++++++++++++++++++++++++++++++++++++++++++++ ++++++++Welcome to use system Collect+++++++++ ++++++++++++++++++++++++++++++++++++++++++++++ EOF ip_info=`ifconfig |grep "Bcast"|tail -1 |awk '{print $2}'|cut -d: -f 2` cpu_info1=`cat /proc/cpuinfo |grep 'model name'|tail -1 |awk -F: '{print $2}'|sed 's/^ //g'|awk '{print $1,$3,$4,$NF}'` cpu_info2=`cat /proc/cpuinfo |grep "physical id"|sort |uniq -c|wc -l` serv_info=`hostname |tail -1` disk_info=`fdisk -l|grep "Disk"|grep -v "identifier"|awk '{print $2,$3,$4}'|sed 's/,//g'` mem_info=`free -m |grep "Mem"|awk '{print "Total",$1,$2"M"}'` load_info=`uptime |awk '{print "Current Load: "$(NF-2)}'|sed 's/\,//g'` mark_info='BeiJing_IDC' echo -e "\033[32m-------------------------------------------\033[1m" echo IPADDR:${ip_info} echo HOSTNAME:$serv_info echo CPU_INFO:${cpu_info1} X${cpu_info2} echo DISK_INFO:$disk_info echo MEM_INFO:$mem_info echo LOAD_INFO:$load_info echo -e "\033[32m-------------------------------------------\033[0m" echo -e -n "\033[36mYou want to write the data to the databases? \033[1m" ;read ensure if [ "$ensure" == "yes" -o "$ensure" == "y" -o "$ensure" == "Y" ];then echo "--------------------------------------------" echo -e '\033[31mmysql -uaudit -p123456 -D audit -e ''' "insert into audit_system values('','${ip_info}','$serv_info','${cpu_info1} X${cpu_info2}','$disk_info','$mem_info','$load_info','$mark_info')" ''' \033[0m ' mysql -uroot -p123456 -D test -e "insert into audit_system values('','${ip_info}','$serv_info','${cpu_info1} X${cpu_info2}','$disk_info','$mem_info','$load_info','$mark_info')" else echo "Please wait,exit......" exit fi
手动读取数据库服务器信息命令:
mysql -uroot -p123 -e 'use wugk1 ;select * from audit_audit_system;'|sed 's/-//g'|grep -v "id"
二、Shell编程实战系统备份脚本
日常企业运维中,需要备份Linux操作系统中重要的文件,例如/etc、/boot分区、重要网站数据等,在备份数据时,由于数据量非常大,需要指定高效的备份方案,如下为常用的备份数据方案:
- 每周日进行完整备份,周一至周六使用增量备份;
- 每周六进行完整备份,周日至周五使用增量备份。
企业备份数据的工具主要有:tar、cp、rsync、scp、sersync、dd等工具。如下为基于开源tar工具实现系统数据备份方案:
Tar工具手动全备份网站,-g参数指定新的快照文件:
tar -g /tmp/snapshot -czvf /tmp/2017_full_system_data.tar.gz /data/sh/
Tar工具手动增量备份网站,-g参数指定全备已生成的快照文件,后续增量备份基于上一个增量备份快照文件:
tar -g /tmp/snapshot -czvf /tmp/2014_add01_system_data.tar.gz /data/sh/
Tar工具全备、增量备份网站,Shell脚本实现自动打包备份编写思路如下:
- 系统备份数据按每天存放;
- 创建完整备份函数块;
- 创建增量备份函数块;
- 根据星期数判断完整或增量;
- 将脚本加入Crontab实现自动备份;
Tar工具全备、增量备份网站,Shell脚本实现自动打包备份,代码如下:
#!/bin/bash #Auto Backup Linux System Files #By author jfedu.net 2017 #Define Path variables SOURCE_DIR=( $* ) TARGET_DIR=/data/backup/ YEAR=`date +%Y` MONTH=`date +%m` DAY=`date +%d` WEEK=`date +%u` A_NAME=`date +%H%M` FILES=system_backup.tgz CODE=$? if [ -z "$*" ];then echo -e "\033[32mUsage:\nPlease Enter Your Backup Files or Directories\n--------------------------------------------\n\nUsage: { $0 /boot /etc}\033[0m" exit fi #Determine Whether the Target Directory Exists if [ ! -d $TARGET_DIR/$YEAR/$MONTH/$DAY ];then mkdir -p $TARGET_DIR/$YEAR/$MONTH/$DAY echo -e "\033[32mThe $TARGET_DIR Created Successfully !\033[0m" fi #EXEC Full_Backup Function Command Full_Backup() { if [ "$WEEK" -eq "7" ];then rm -rf $TARGET_DIR/snapshot cd $TARGET_DIR/$YEAR/$MONTH/$DAY ;tar -g $TARGET_DIR/snapshot -czvf $FILES ${SOURCE_DIR[@]} [ "$CODE" == "0" ]&&echo -e "--------------------------------------------\n\033[32mThese Full_Backup System Files Backup Successfully !\033[0m" fi } #Perform incremental BACKUP Function Command Add_Backup() { if [ $WEEK -ne "7" ];then cd $TARGET_DIR/$YEAR/$MONTH/$DAY ;tar -g $TARGET_DIR/snapshot -czvf $A_NAME$FILES ${SOURCE_DIR[@]} [ "$CODE" == "0" ]&&echo -e "-----------------------------------------\n\033[32mThese Add_Backup System Files $TARGET_DIR/$YEAR/$MONTH/$DAY/${YEAR}_$A_NAME$FILES Backup Successfully !\033[0m" fi } sleep 3 Full_Backup;Add_Backup
Crontab任务计划中添加如下语句,每天凌晨1点整执行备份脚本即可:
0 1 * * * /bin/sh /data/sh/auto_backup.sh /boot /etc/ >> /tmp/back.log 2>&1
三、Shell编程实战拒绝恶意IP登录
企业服务器暴露在外网,每天会有大量的人使用各种用户名和密码尝试登陆服务器,如果让其一直尝试,难免会猜出密码,通过开发Shell脚本,可以自动将尝试登陆服务器错误密码次数的IP列表加入到防火墙配置中。
Shell脚本实现服务器拒绝恶意IP登陆,编写思路如下:
- 登陆服务器日志/var/log/secure;
- 检查日志中认证失败的行并打印其IP地址;
- 将IP地址写入至防火墙;
- 禁止该IP访问服务器SSH 22端口;
- 将脚本加入Crontab实现自动禁止恶意IP;
Shell脚本实现服务器拒绝恶意IP登陆,代码如下:
#!/bin/bash #Auto drop ssh failed IP address #By author jfedu.net 2017 #Define Path variables SEC_FILE=/var/log/secure IP_ADDR=`awk '{print $0}' /var/log/secure|grep -i "fail"| egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort -nr | uniq -c |awk '$1>=15 {print $2}'` IPTABLE_CONF=/etc/sysconfig/iptables echo cat <<EOF ++++++++++++++welcome to use ssh login drop failed ip+++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++------------------------------------++++++++++++++++++ EOF echo for ((j=0;j<=6;j++)) ;do echo -n "-";sleep 1 ;done echo for i in `echo $IP_ADDR` do cat $IPTABLE_CONF |grep $i >/dev/null if [ $? -ne 0 ];then sed -i "/lo/a -A INPUT -s $i -m state --state NEW -m tcp -p tcp --dport 22 -j DROP" $IPTABLE_CONF fi done NUM=`find /etc/sysconfig/ -name iptables -a -mmin -1|wc -l` if [ $NUM -eq 1 ];then /etc/init.d/iptables restart fi
四、Shell编程实战MYSQL主从复制
MYSQL数据库服务器应用主要应用于与动态网站结合,存放网站必要的数据,例如订单、交易、员工表、薪资等记录,为了实现数据备份,需引入MYSQL主从架构,MYSQL主从架构脚本可以实现自动化安装、配置和管理。
Shell脚本实现服务器MYSQL一键YUM安装配置,编写思路如下:
MYSQL主库的操作:
- 主库上安装MYSQL,设置server-id、bin-log;
- 授权复制同步的用户,对客户端授权;
- 确认bin-log文件名、position位置点。
MYSQL丛库的操作:
- 从库上安装MYSQL,设置server-id;
- change master 指定主库和bin-log名和position;
- start slave; 启动丛库IO线程;
- show slave status\G查看主从的状态。
Shell脚本实现服务器MYSQL一键YUM安装配置,需要提前手动授权主库可以免密码登录丛库服务器,代码如下:
#!/bin/bash #Auto install Mysql AB Repliation #By author jfedu.net 2017 #Define Path variables MYSQL_SOFT="mysql mysql-server mysql-devel php-mysql mysql-libs" NUM=`rpm -qa |grep -i mysql |wc -l` INIT="/etc/init.d/mysqld" CODE=$? #Mysql To Install 2017 if [ $NUM -ne 0 -a -f $INIT ];then echo -e "\033[32mThis Server Mysql already Install.\033[0m" read -p "Please ensure yum remove Mysql Server,YES or NO": INPUT if [ $INPUT == "y" -o $INPUT == "yes" ];then yum remove $MYSQL_SOFT -y ;rm -rf /var/lib/mysql /etc/my.cnf yum install $MYSQL_SOFT -y else echo fi else yum remove $MYSQL_SOFT -y ;rm -rf /var/lib/mysql /etc/my.cnf yum install $MYSQL_SOFT -y if [ $CODE -eq 0 ];then echo -e "\033[32mThe Mysql Install Successfully.\033[0m" else echo -e "\033[32mThe Mysql Install Failed.\033[0m" exit 1 fi fi my_config(){ cat >/etc/my.cnf<<EOF [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql symbolic-links=0 log-bin=mysql-bin server-id = 1 auto_increment_offset=1 auto_increment_increment=2 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid EOF } my_config /etc/init.d/mysqld restart ps -ef |grep mysql MYSQL_CONFIG(){ #Master Config Mysql mysql -e "grant replication slave on *.* to 'tongbu'@'%' identified by '123456';" MASTER_FILE=`mysql -e "show master status;"|tail -1|awk '{print $1}'` MASTER_POS=`mysql -e "show master status;"|tail -1|awk '{print $2}'` MASTER_IPADDR=`ifconfig eth0|grep "Bcast"|awk '{print $2}'|cut -d: -f2` read -p "Please Input Slave IPaddr: " SLAVE_IPADDR #Slave Config Mysql ssh -l root $SLAVE_IPADDR "yum remove $MYSQL_SOFT -y ;rm -rf /var/lib/mysql /etc/my.cnf ;yum install $MYSQL_SOFT -y" ssh -l root $SLAVE_IPADDR "$my_config" #scp -r /etc/my.cnf root@192.168.111.129:/etc/ ssh -l root $SLAVE_IPADDR "sed -i 's#server-id = 1#server-id = 2#g' /etc/my.cnf" ssh -l root $SLAVE_IPADDR "sed -i '/log-bin=mysql-bin/d' /etc/my.cnf" ssh -l root $SLAVE_IPADDR "/etc/init.d/mysqld restart" ssh -l root $SLAVE_IPADDR "mysql -e \"change master to master_host='$MASTER_IPADDR',master_user='tongbu',master_password='123456',master_log_file='$MASTER_FILE',master_log_pos=$MASTER_POS;\"" ssh -l root $SLAVE_IPADDR "mysql -e \"slave start;\"" ssh -l root $SLAVE_IPADDR "mysql -e \"show slave status\G;\"" } read -p "Please ensure your Server is Master and you will config mysql Replication?yes or no": INPUT if [ $INPUT == "y" -o $INPUT == "yes" ];then MYSQL_CONFIG else exit 0 fi
五、Shell编程实战修改IP及主机名
企业中服务器IP地址系统通过自动化工具安装完系统,IP均是自动获取的,而服务器要求固定的静态IP,百台服务器手工去配置静态IP是不可取的,可以基于Shell脚本自动修改IP、主机名等信息。
Shell脚本实现服务器IP、主机名自动修改及配置,编写思路如下:
- 静态IP修改;
- 动态IP修改;
- 根据IP-生成主机名并配置;
- 修改DNS域名解析;
Shell脚本实现服务器IP、主机名自动修改及配置,代码如下:
#!/bin/bash #Auto Change ip netmask gateway scripts #By author jfedu.net 2017 #Define Path variables ETHCONF=/etc/sysconfig/network-scripts/ifcfg-eth0 HOSTS=/etc/hosts NETWORK=/etc/sysconfig/network DIR=/data/backup/`date +%Y%m%d` NETMASK=255.255.255.0 echo "----------------------------" judge_ip(){ read -p "Please enter ip Address,example 192.168.0.11 ip": IPADDR echo $IPADDR|grep -v "[Aa-Zz]"|grep --color -E "([0-9]{1,3}\.){3}[0-9]{1,3}" } count_ip(){ count=(`echo $IPADDR|awk -F. '{print $1,$2,$3,$4}'`) IP1=${count[0]} IP2=${count[1]} IP3=${count[2]} IP4=${count[3]} } ip_check() { judge_ip while [ $? -ne 0 ] do judge_ip done count_ip while [ "$IP1" -lt 0 -o "$IP1" -ge 255 -o "$IP2" -ge 255 -o "$IP3" -ge 255 -o "$IP4" -ge 255 ] do judge_ip while [ $? -ne 0 ] do judge_ip done count_ip done } change_ip() { if [ ! -d $DIR ];then mkdir -p $DIR fi echo "The Change ip address to Backup Interface eth0" cp $ETHCONF $DIR grep "dhcp" $ETHCONF if [ $? -eq 0 ];then read -p "Please enter ip Address:" IPADDR sed -i 's/dhcp/static/g' $ETHCONF echo -e "IPADDR=$IPADDR\nNETMASK=$NETMASK\nGATEWAY=`echo $IPADDR|awk -F. '{print $1"."$2"."$3}'`.2" >>$ETHCONF echo "The IP configuration success. !" else echo -n "Static IP has been configured,please confirm whether to modify,yes or No": read i fi if [ "$i" == "y" -o "$i" == "yes" ];then ip_check sed -i -e '/IPADDR/d' -e '/NETMASK/d' -e '/GATEWAY/d' $ETHCONF echo -e "IPADDR=$IPADDR\nNETMASK=$NETMASK\nGATEWAY=`echo $IPADDR|awk -F. '{print $1"."$2"."$3}'`.2" >>$ETHCONF echo "The IP configuration success. !" echo else echo "Static IP already exists,please exit." exit $? fi } change_hosts() { if [ ! -d $DIR ];then mkdir -p $DIR fi cp $HOSTS $DIR ip_check host=` echo $IPADDR|sed 's/\./-/g'|awk '{print "BJ-IDC-"$0"-jfedu.net"}'` cat $HOSTS |grep "$host" if [ $? -ne 0 ];then echo "$IPADDR $host" >> $HOSTS echo "The hosts modify success " fi grep "$host" $NETWORK if [ $? -ne 0 ];then sed -i "s/^HOSTNAME/#HOSTNAME/g" $NETWORK echo "NETWORK=$host" >>$NETWORK hostname $host;su fi } PS3="Please Select configuration ip or configuration host:" select i in "modify_ip" "modify_hosts" "exit" do case $i in modify_ip) change_ip ;; modify_hosts) change_hosts ;; exit) exit ;; *) echo -e "1) modify_ip\n2) modify_ip\n3)exit" esac done
六、Shell编程实战Zabbix安装配置
Zabbix是一款分布式监控系统,基于C/S模式,需在服务器安装Zabbix_server,在客户端安装Zabbix_agent,通过Shell脚本可以更快速的实现该需求。
Shell脚本实现Zabbix服务器端和客户端自动安装,编写思路如下:
- Zabbix软件的版本源码安装、路径、--enable-server、--enable-agent;
- cp zabbix_agentd启动进程-/etc/init.d/zabbix_agentd、给执行x权限;
- 配置zabbix_agentd.conf文件,指定server IP变量;
- 指定客户端的Hostname其实可以等于客户端IP地址;
- 启动zabbix_agentd服务,创建zabbix user。
Shell脚本实现Zabbix服务器端和客户端自动安装,代码如下:
#!/bin/bash #Auto install zabbix server and client #By author jfedu.net 2017 #Define Path variables ZABBIX_SOFT="zabbix-3.2.6.tar.gz" INSTALL_DIR="/usr/local/zabbix/" SERVER_IP="192.168.111.128" IP=`ifconfig|grep Bcast|awk '{print $2}'|sed 's/addr://g'` SERVER_INSTALL(){ yum -y install curl curl-devel net-snmp net-snmp-devel perl-DBI groupadd zabbix ;useradd -g zabbix zabbix;usermod -s /sbin/nologin zabbix tar -xzf $ZABBIX_SOFT;cd `echo $ZABBIX_SOFT|sed 's/.tar.*//g'` ./configure --prefix=/usr/local/zabbix --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl &&make install if [ $? -eq 0 ];then ln -s /usr/local/zabbix/sbin/zabbix_* /usr/local/sbin/ fi cd - ;cd zabbix-3.2.6 cp misc/init.d/tru64/{zabbix_agentd,zabbix_server} /etc/init.d/ ;chmod o+x /etc/init.d/zabbix_* mkdir -p /var/www/html/zabbix/;cp -a frontends/php/* /var/www/html/zabbix/ #config zabbix server cat >$INSTALL_DIR/etc/zabbix_server.conf<<EOF LogFile=/tmp/zabbix_server.log DBHost=localhost DBName=zabbix DBUser=zabbix DBPassword=123456 EOF #config zabbix agentd cat >$INSTALL_DIR/etc/zabbix_agentd.conf<<EOF LogFile=/tmp/zabbix_agentd.log Server=$SERVER_IP ServerActive=$SERVER_IP Hostname = $IP EOF #start zabbix agentd /etc/init.d/zabbix_server restart /etc/init.d/zabbix_agentd restart /etc/init.d/iptables stop setenforce 0 } AGENT_INSTALL(){ yum -y install curl curl-devel net-snmp net-snmp-devel perl-DBI groupadd zabbix ;useradd -g zabbix zabbix;usermod -s /sbin/nologin zabbix tar -xzf $ZABBIX_SOFT;cd `echo $ZABBIX_SOFT|sed 's/.tar.*//g'` ./configure --prefix=/usr/local/zabbix --enable-agent&&make install if [ $? -eq 0 ];then ln -s /usr/local/zabbix/sbin/zabbix_* /usr/local/sbin/ fi cd - ;cd zabbix-3.2.6 cp misc/init.d/tru64/zabbix_agentd /etc/init.d/zabbix_agentd ;chmod o+x /etc/init.d/zabbix_agentd #config zabbix agentd cat >$INSTALL_DIR/etc/zabbix_agentd.conf<<EOF LogFile=/tmp/zabbix_agentd.log Server=$SERVER_IP ServerActive=$SERVER_IP Hostname = $IP EOF #start zabbix agentd /etc/init.d/zabbix_agentd restart /etc/init.d/iptables stop setenforce 0 } read -p "Please confirm whether to install Zabbix Server,yes or no? " INPUT if [ $INPUT == "yes" -o $INPUT == "y" ];then SERVER_INSTALL else AGENT_INSTALL fi
七、Shell编程实战Nginx虚拟主机
Nginx WEB服务器的最大特点在于Nginx常被用于负载均衡、反向代理,单台Nginx服务器配置多个虚拟主机,百台服务器配置N多虚拟主机,基于Shell脚本可以更加高效的配置虚拟主机及添加、管理。
Shell脚本实现Nginx自动安装及虚拟主机的维护,编写思路如下:
- 脚本指定参数v1.jfedu.net;
- 创建v1.jfedu.net同时创建目录/var/www/v1;
- 将Nginx虚拟主机配置定向到新的目录;
- 重复虚拟主机不再添加。
Shell脚本实现Nginx自动安装及虚拟主机的维护,代码如下:
#!/bin/bash #Auto config Nginx virtual Hosts #By author jfedu.net 2017 #Define Path variables NGINX_CONF="/usr/local/nginx/conf/" NGINX_MAKE="--user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module" NGINX_SBIN="/usr/local/nginx/sbin/nginx" NGINX_INSTALL(){ #Install Nginx server NGINX_FILE=nginx-1.12.0.tar.gz NGINX_DIR=`echo $NGINX_FILE|sed 's/.tar*.*//g'` if [ ! -e /usr/local/nginx/ -a ! -e /etc/nginx/ ];then pkill nginx wget -c http://nginx.org/download/$NGINX_FILE yum install pcre-devel pcre -y rm -rf $NGINX_DIR ;tar xf $NGINX_FILE cd $NGINX_DIR;useradd www;./configure $NGINX_MAKE make &&make install grep -vE "#|^$" $NGINX_CONF/nginx.conf >$NGINX_CONF/nginx.conf.swp \mv $NGINX_CONF/nginx.conf.swp $NGINX_CONF/nginx.conf for i in `seq 1 6`;do sed -i '$d' $NGINX_CONF/nginx.conf;done echo "}" >>$NGINX_CONF/nginx.conf cd ../ fi } NGINX_CONFIG(){ #config tomcat nginx vhosts grep "include domains" $NGINX_CONF/nginx.conf >>/dev/null if [ $? -ne 0 ];then #sed -i '$d' $NGINX_CONF/nginx.conf echo -e "\ninclude domains/*;\n}" >>$NGINX_CONF/nginx.conf mkdir -p $NGINX_CONF/domains/ fi VHOSTS=$1 ls $NGINX_CONF/domains/$VHOSTS>>/dev/null 2>&1 if [ $? -ne 0 ];then #cp -r xxx.jfedu.net $NGINX_CONF/domains/$VHOSTS #sed -i "s/xxx/$VHOSTS/g" $NGINX_CONF/domains/$VHOSTS cat>$NGINX_CONF/domains/$VHOSTS<<EOF #vhost server $VHOSTS server { listen 80; server_name $VHOSTS; location / { root /data/www/$VHOSTS/; index index.html index.htm; } } EOF mkdir -p /data/www/$VHOSTS/ cat>/data/www/$VHOSTS/index.html<<EOF <html> <h1><center>The First Test Nginx page.</center></h1> <hr color="red"> <h2><center>$VHOSTS</center></h2> </html> EOF echo -e "\033[32mThe $VHOSTS Config success,You can to access http://$VHOSTS/\033[0m" NUM=`ps -ef |grep nginx|grep -v grep|grep -v auto|wc -l` $NGINX_SBIN -t >>/dev/null 2>&1 if [ $? -eq 0 -a $NUM -eq 0 ];then $NGINX_SBIN else $NGINX_SBIN -t >>/dev/null 2>&1 if [ $? -eq 0 ];then $NGINX_SBIN -s reload fi fi else echo -e "\033[32mThe $VHOSTS has been config,Please exit.\033[0m" fi } if [ -z $1 ];then echo -e "\033[32m--------------------\033[0m" echo -e "\033[32mPlease enter sh $0 xx.jf.com.\033[0m" exit 0 fi NGINX_INSTALL NGINX_CONFIG $1
八、Shell编程实战Nginx、Tomcat脚本
Tomcat用于发布JSP WEB页面,根据企业实际需求,会在单台服务器配置N个Tomcat实例,同时手动将Tomcat创建后的实例加入至Nginx虚拟主机中,同时重启Nginx,开发Nginx、Tomcat自动创建Tomcat实例及Nginx虚拟主机管理脚本能让大大的减轻人工的干预,实现快速的交付。
Shell脚本实现Nginx自动安装、虚拟主机及自动将Tomcat加入至虚拟主机,编写思路如下:
- 手动拷贝Tomcat与脚本一致目录(可自动修改);
- 手动修改Tomcat端口为6001、7001、8001(可自动修改);
- 脚本指定参数v1.jfedu.net;
- 创建v1.jfedu.net Tomcat实例;
- 修改Tomcat实例端口,保证Port唯一;
- 将Tomcat实例加入Nginx虚拟主机;
- 重复创建Tomcat实例,端口自动增加,并加入原Nginx虚拟主机,实现负载均衡;
Shell脚本实现Nginx自动安装、虚拟主机及自动将Tomcat加入至虚拟主机,代码如下:
#!/bin/bash #Auto config Nginx and tomcat cluster #By author jfedu.net 2017 #Define Path variables NGINX_CONF="/usr/local/nginx/conf/" install_nginx(){ NGINX_FILE=nginx-1.10.2.tar.gz NGINX_DIR=`echo $NGINX_FILE|sed 's/.tar*.*//g'` wget -c http://nginx.org/download/$NGINX_FILE yum install pcre-devel pcre -y rm -rf $NGINX_DIR ;tar xf $NGINX_FILE cd $NGINX_DIR;useradd www;./configure --user=www --group=www --prefix=/usr/local/nginx2 --with-http_stub_status_module --with-http_ssl_module make &&make install cd ../ } install_tomcat(){ JDK_FILE="jdk1.7.0_25.tar.gz" JDK_DIR=`echo $JDK_FILE|sed 's/.tar.*//g'` tar -xzf $JDK_FILE ;mkdir -p /usr/java/ ;mv $JDK_DIR /usr/java/ sed -i '/JAVA_HOME/d;/JAVA_BIN/d;/JAVA_OPTS/d' /etc/profile cat >> /etc/profile <<EOF export JAVA_HOME=/export/servers/$JAVA_DIR export JAVA_BIN=/export/servers/$JAVA_DIR/bin export PATH=\$JAVA_HOME/bin:\$PATH export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar export JAVA_HOME JAVA_BIN PATH CLASSPATH EOF source /etc/profile;java -version #install tomcat start ls tomcat } config_tomcat_nginx(){ #config tomcat nginx vhosts grep "include domains" $NGINX_CONF/nginx.conf >>/dev/null if [ $? -ne 0 ];then sed -i '$d' $NGINX_CONF/nginx.conf echo -e "\ninclude domains/*;\n}" >>$NGINX_CONF/nginx.conf mkdir -p $NGINX_CONF/domains/ fi VHOSTS=$1 NUM=`ls /usr/local/|grep -c tomcat` if [ $NUM -eq 0 ];then cp -r tomcat /usr/local/tomcat_$VHOSTS cp -r xxx.jfedu.net $NGINX_CONF/domains/$VHOSTS #sed -i "s/VHOSTS/$VHOSTS/g" $NGINX_CONF/domains/$VHOSTS sed -i "s/xxx/$VHOSTS/g" $NGINX_CONF/domains/$VHOSTS exit 0 fi #-------------------------------- #VHOSTS=$1 VHOSTS_NUM=`ls $NGINX_CONF/domains/|grep -c $VHOSTS` SERVER_NUM=`grep -c "127" $NGINX_CONF/domains/$VHOSTS` SERVER_NUM_1=`expr $SERVER_NUM + 1` rm -rf /tmp/.port.txt for i in `find /usr/local/ -maxdepth 1 -name "tomcat*"`;do grep "port" $i/conf/server.xml |egrep -v "\--|8080|SSLEnabled"|awk '{print $2}'|sed 's/port=//g;s/\"//g'|sort -nr >>/tmp/.port.txt done MAX_PORT=`cat /tmp/.port.txt|grep -v 8443|sort -nr|head -1` PORT_1=`expr $MAX_PORT - 2000 + 1` PORT_2=`expr $MAX_PORT - 1000 + 1` PORT_3=`expr $MAX_PORT + 1` if [ $VHOSTS_NUM -eq 1 ];then read -p "The $VHOSTS is exists,You sure create mulit Tomcat for the $VHOSTS? yes or no " INPUT if [ $INPUT == "YES" -o $INPUT == "Y" -o $INPUT == "yes" ];then cp -r tomcat /usr/local/tomcat_${VHOSTS}_${SERVER_NUM_1} sed -i "s/6001/$PORT_1/g" /usr/local/tomcat_${VHOSTS}_${SERVER_NUM_1}/conf/server.xml sed -i "s/7001/$PORT_2/g" /usr/local/tomcat_${VHOSTS}_${SERVER_NUM_1}/conf/server.xml sed -i "s/8001/$PORT_3/g" /usr/local/tomcat_${VHOSTS}_${SERVER_NUM_1}/conf/server.xml sed -i "/^upstream/a server 127.0.0.1:${PORT_2} weight=1 max_fails=2 fail_timeout=30s;" $NGINX_CONF/domains/$VHOSTS exit 0 fi exit fi cp -r tomcat /usr/local/tomcat_$VHOSTS cp -r xxx.jfedu.net $NGINX_CONF/domains/$VHOSTS sed -i "s/VHOSTS/$VHOSTS/g" $NGINX_CONF/domains/$VHOSTS sed -i "s/xxx/$VHOSTS/g" $NGINX_CONF/domains/$VHOSTS sed -i "s/7001/${PORT_2}/g" $NGINX_CONF/domains/$VHOSTS #######config tomcat sed -i "s/6001/$PORT_1/g" /usr/local/tomcat_${VHOSTS}/conf/server.xml sed -i "s/7001/$PORT_2/g" /usr/local/tomcat_${VHOSTS}/conf/server.xml sed -i "s/8001/$PORT_3/g" /usr/local/tomcat_${VHOSTS}/conf/server.xml } if [ ! -d $NGINX_CONF -o ! -d /usr/java/$JDK_DIR ];then install_nginx install_tomcat fi config_tomcat_nginx $1
九、Shell编程实战Docker管理脚本
Docker虚拟化是目前主流的虚拟化解决方案,越来越多的企业在使用Docker轻量级虚拟化,构建、维护和管理Docker虚拟化平台是运维人员非常重要的一个环节,开发Docker Shell脚本可以在命令行界面快速管理和维护Docker。
Shell脚本实现Docker自动安装、自动导入镜像、创建虚拟机、指定IP地址、将创建的Docker虚拟机加入Excel存档或者加入MYSQL数据库,编写思路如下:
- 基于CentOS6.5+或者7.x YUM安装Docker;
- Docker脚本参数指定CPU、内存、硬盘容量;
- Docker自动检测局域网IP并赋予Docker虚拟机;
- Docker基于pipework指定IP;
- 将创建的Docker虚拟机加入至CSV(Excel)或者MYSQL库;
Shell脚本实现Docker自动安装、自动导入镜像、创建虚拟机、指定IP地址、将创建的Docker虚拟机加入CSV(Excel)存档或者加入MYSQL数据库,代码如下:
#!/bin/bash #Auto install docker and Create VM #By author jfedu.net 2017 #Define Path variables IPADDR=`ifconfig|grep -E "\<inet\>"|awk '{print $2}'|grep "192.168"|head -1` GATEWAY=`route -n|grep "UG"|awk '{print $2}'|grep "192.168"|head -1` IPADDR_NET=`ifconfig|grep -E "\<inet\>"|awk '{print $2}'|grep "192.168"|head -1|awk -F. '{print $1"."$2"."$3"."}'` LIST="/root/docker_vmlist.csv" if [ ! -f /usr/sbin/ifconfig ];then yum install net-tools* -y fi for i in `seq 1 253`;do ping -c 1 ${IPADDR_NET}${i} ;[ $? -ne 0 ]&& DOCKER_IPADDR="${IPADDR_NET}${i}" &&break;done >>/dev/null 2>&1 echo "##################" echo -e "Dynamic get docker IP,The Docker IP address\n\n$DOCKER_IPADDR" NETWORK=( HWADDR=`ifconfig eth0|grep ether|awk '{print $2}'` IPADDR=`ifconfig eth0|grep -E "\<inet\>"|awk '{print $2}'` NETMASK=`ifconfig eth0|grep -E "\<inet\>"|awk '{print $4}'` GATEWAY=`route -n|grep "UG"|awk '{print $2}'` ) if [ -z "$1" -o -z "$2" ];then echo -e "\033[32m---------------------------------\033[0m" echo -e "\033[32mPlease exec $0 CPU(C) MEM(G),example $0 4 8\033[0m" exit 0 fi #CPU=`expr $2 - 1` if [ ! -e /usr/bin/bc ];then yum install bc -y >>/dev/null 2>&1 fi CPU_ALL=`cat /proc/cpuinfo |grep processor|wc -l` if [ ! -f $LIST ];then CPU_COUNT=$1 CPU_1="0" CPU1=`expr $CPU_1 + 0` CPU2=`expr $CPU1 + $CPU_COUNT - 1` if [ $CPU2 -gt $CPU_ALL ];then echo -e "\033[32mThe System CPU count is $CPU_ALL,not more than it.\033[0m" exit fi else CPU_COUNT=$1 CPU_1=`cat $LIST|tail -1|awk -F"," '{print $4}'|awk -F"-" '{print $2}'` CPU1=`expr $CPU_1 + 1` CPU2=`expr $CPU1 + $CPU_COUNT - 1` if [ $CPU2 -gt $CPU_ALL ];then echo -e "\033[32mThe System CPU count is $CPU_ALL,not more than it.\033[0m" exit fi fi MEM_F=`echo $2 \* 1024|bc` MEM=`printf "%.0f\n" $MEM_F` DISK=20 USER=$3 REMARK=$4 ping $DOCKER_IPADDR -c 1 >>/dev/null 2>&1 if [ $? -eq 0 ];then echo -e "\033[32m---------------------------------\033[0m" echo -e "\033[32mThe IP address to be used,Please change other IP,exit.\033[0m" exit 0 fi if [ ! -e /usr/bin/docker ];then yum install docker* device-mapper* -y mkdir -p /export/docker/ cd /var/lib/ ;rm -rf docker ;ln -s /export/docker/ . mkdir -p /var/lib/docker/devicemapper/devicemapper dd if=/dev/zero of=/var/lib/docker/devicemapper/devicemapper/data bs=1G count=0 seek=2000 service docker start if [ $? -ne 0 ];then echo "Docker install error ,please check." exit fi fi cd /etc/sysconfig/network-scripts/ mkdir -p /data/backup/`date +%Y%m%d-%H%M` yes|cp ifcfg-eth* /data/backup/`date +%Y%m%d-%H%M`/ if [ -e /etc/sysconfig/network-scripts/ifcfg-br0 ];then echo else cat >ifcfg-eth0 <<EOF DEVICE=eth0 BOOTPROTO=none ${NETWORK[0]} NM_CONTROLLED=no ONBOOT=yes TYPE=Ethernet BRIDGE="br0" ${NETWORK[1]} ${NETWORK[2]} ${NETWORK[3]} USERCTL=no EOF cat >ifcfg-br0 <<EOF DEVICE="br0" BOOTPROTO=none ${NETWORK[0]} IPV6INIT=no NM_CONTROLLED=no ONBOOT=yes TYPE="Bridge" ${NETWORK[1]} ${NETWORK[2]} ${NETWORK[3]} USERCTL=no EOF /etc/init.d/network restart fi echo 'Your can restart Ethernet Service: /etc/init.d/network restart !' echo '---------------------------------------------------------' cd - #######create docker container service docker status >>/dev/null if [ $? -ne 0 ];then service docker restart fi NAME="Docker_`echo $DOCKER_IPADDR|awk -F"." '{print $(NF-1)"_"$NF}'`" IMAGES=`docker images|grep -v "REPOSITORY"|grep -v "none"|grep "jfedu"|head -1|awk '{print $1}'` if [ -z $IMAGES ];then echo "Plesae Download Docker Centos Images,you can to be use docker search centos,and docker pull centos6.5-ssh,exit 0" if [ ! -f jfedu_centos68.tar ];then echo "Please upload jfedu_centos68.tar for docker server." exit fi cat jfedu_centos68.tar|docker import - jfedu_centos6.8 fi IMAGES=`docker images|grep -v "REPOSITORY"|grep -v "none"|grep "jfedu"|head -1|awk '{print $1}'` CID=$(docker run -itd --privileged --cpuset-cpus=${CPU1}-${CPU2} -m ${MEM}m --net=none --name=$NAME $IMAGES /bin/bash) echo $CID docker ps -a |grep "$NAME" pipework br0 $NAME $DOCKER_IPADDR/24@$IPADDR docker exec $NAME /etc/init.d/sshd start if [ ! -e $LIST ];then echo "编号,容器ID,容器名称,CPU,内存,硬盘,容器IP,宿主机IP,使用人,备注" >$LIST fi ################### NUM=`cat $LIST |grep -v CPU|tail -1|awk -F, '{print $1}'` if [[ $NUM -eq "" ]];then NUM="1" else NUM=`expr $NUM + 1` fi ################## echo -e "\033[32mCreate virtual client Successfully.\n$NUM `echo $CID|cut -b 1-12`,$NAME,$CPU1-$CPU2,${MEM}M,${DISK}G,$DOCKER_IPADDR,$IPADDR,$USER,$REMARK\033[0m" if [ -z $USER ];then USER="NULL" REMARK="NULL" fi echo $NUM,`echo $CID|cut -b 1-12`,$NAME,$CPU1-$CPU2,${MEM}M,${DISK}G,$DOCKER_IPADDR,$IPADDR,$USER,$REMARK >>$LIST rm -rf /root/docker_vmlist_* iconv -c -f utf-8 -t gb2312 $LIST -o /root/docker_vmlist_`date +%H%M`.csv
十、Shell编程实战Bind管理脚本
Bind主要应用于企业DNS构建平台,而DNS用于将域名与IP进行解析,用户在浏览器只需输入域名,即可访问服务器IP地址的虚拟主机网站。
Bind难点在于创建各种记录,例如A记录、mail记录、反向记录、资源记录,基于Shell脚本可以减轻人工的操作,节省大量的时间成本。
Shell脚本实现Bind自动安装、初始化Bind环境、自动添加A记录、反向记录、批量添加A记录,编写思路如下:
- YUM方式自动安装Bind;
- 自动初始化Bind配置;
- 创建安装、初始化、添加记录函数;
- 自动添加单个A记录及批量添加A记录和反向记录;
Shell脚本实现Bind自动安装、初始化Bind环境、自动添加A记录、反向记录、批量添加A记录,代码如下:
#!/bin/bash #Auto install config bind server #By author jfedu.net 2017 #Define Path variables BND_ETC=/var/named/chroot/etc BND_VAR=/var/named/chroot/var/named BAK_DIR=/data/backup/dns_`date +%Y%m%d-%H%M` ##Backup named server if [ ! -d $BAK_DIR ];then echo "Please waiting Backup Named Config ............" mkdir -p $BAK_DIR cp -a /var/named/chroot/{etc,var} $BAK_DIR cp -a /etc/named.* $BAK_DIR fi ##Define Shell Install Function Install () { if [ ! -e /etc/init.d/named ];then yum install bind* -y else echo ------------------------------------------------- echo "The Named Server is exists ,Please exit ........." sleep 1 fi } ##Define Shell Init Function Init_Config () { sed -i -e 's/localhost;/any;/g' -e '/port/s/127.0.0.1/any/g' /etc/named.conf echo ------------------------------------------------- sleep 2 echo "The named.conf config Init success !" } ##Define Shell Add Name Function Add_named () { ##DNS name read -p "Please Insert Into Your Add Name ,Example 51cto.com :" NAME echo $NAME |grep -E "com|cn|net|org" while [ "$?" -ne 0 ] do read -p "Please reInsert Into Your Add Name ,Example 51cto.com :" NAME echo $NAME |grep -E "com|cn|net|org" done ## IP address read -p "Please Insert Into Your Name Server IP ADDress:" IP echo $IP |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" while [ "$?" -ne "0" ] do read -p "Please reInsert Into Your Name Server IP ADDress:" IP echo $IP |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" done ARPA_IP=`echo $IP|awk -F. '{print $3"."$2"."$1}'` ARPA_IP1=`echo $IP|awk -F. '{print $4}'` cd $BND_ETC grep "$NAME" named.rfc1912.zones if [ $? -eq 0 ];then echo "The $NAME IS exist named.rfc1912.zones conf ,please exit ..." exit else read -p "Please Insert Into SLAVE Name Server IP ADDress:" SLAVE echo $SLAVE |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" while [ "$?" -ne "0" ] do read -p "Please Insert Into SLAVE Name Server IP ADDress:" SLAVE echo $SLAVE |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" done grep "rev" named.rfc1912.zones if [ $? -ne 0 ];then cat >>named.rfc1912.zones <<EOF #`date +%Y-%m-%d` Add $NAME CONFIG zone "$NAME" IN { type master; file "$NAME.zone"; allow-update { none; }; }; zone "$ARPA_IP.in-addr.arpa" IN { type master; file "$ARPA_IP.rev"; allow-update { none; }; }; EOF else cat >>named.rfc1912.zones <<EOF #`date +%Y-%m-%d` Add $NAME CONFIG zone "$NAME" IN { type master; file "$NAME.zone"; allow-update { none; }; }; EOF fi fi [ $? -eq 0 ]&& echo "The $NAME config name.rfc1912.zones success !" sleep 3 ;echo "Please waiting config $NAME zone File ............." cd $BND_VAR read -p "Please insert Name DNS A HOST ,EXample www or mail :" HOST read -p "Please insert Name DNS A NS IP ADDR ,EXample 192.168.111.130 :" IP_HOST echo $IP_HOST |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" ARPA_IP2=`echo $IP_HOST|awk -F. '{print $3"."$2"."$1}'` ARPA_IP3=`echo $IP_HOST|awk -F. '{print $4}'` while [ "$?" -ne "0" ] do read -p "Please Reinsert Name DNS A IPADDRESS ,EXample 192.168.111.130 :" IP_HOST echo $IP_HOST |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" done cat >$NAME.zone <<EOF \$TTL 86400 @ IN SOA localhost. root.localhost. ( 43 ; serial (d. adams) 1H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum IN NS $NAME. EOF REV=`ls *.rev` ls *.rev >>/dev/null if [ $? -ne 0 ];then cat >>$ARPA_IP.rev <<EOF \$TTL 86400 @ IN SOA localhost. root.localhost. ( 1997022703 ; Serial 28800 ; Refresh 14400 ; Retry 3600000 ; Expire 86400 ) ; Minimum IN NS $NAME. EOF echo "$HOST IN A $IP_HOST" >>$NAME.zone echo "$ARPA_IP3 IN PTR $HOST.$NAME." >>$ARPA_IP.rev [ $? -eq 0 ]&& echo -e "The $NAME config success:\n$HOST IN A $IP_HOST\n$ARPA_IP3 IN PTR $HOST.$NAME." else sed -i "9a IN NS $NAME." $REV echo "$HOST IN A $IP_HOST" >>$NAME.zone echo "$ARPA_IP3 IN PTR $HOST.$NAME." >>$REV [ $? -eq 0 ]&& echo -e "The $NAME config success1:\n$HOST IN A $IP_HOST\n$ARPA_IP3 IN PTR $HOST.$NAME." fi } ##Define Shell List A Function Add_A_List () { if cd $BND_VAR REV=`ls *.rev` read -p "Please Insert Into Your Add Name ,Example 51cto.com :" NAME [ ! -e "$NAME.zone" ];then echo "The $NAME.zone File is not exist ,Please ADD $NAME.zone File :" Add_named ; else read -p "Please Enter List Name A NS File ,Example /tmp/name_list.txt: " FILE if [ -e $FILE ];then for i in `cat $FILE|awk '{print $2}'|sed "s/$NAME//g"|sed 's/\.$//g'` #for i in `cat $FILE|awk '{print $1}'|sed "s/$NAME//g"|sed 's/\.$//g'` do j=`awk -v I="$i.$NAME" '{if(I==$2)print $1}' $FILE` echo ----------------------------------------------------------- echo "The $NAME.zone File is exist ,Please Enter insert NAME HOST ...." sleep 1 ARPA_IP=`echo $j|awk -F. '{print $3"."$2"."$1}'` ARPA_IP2=`echo $j|awk -F. '{print $4}'` echo "$i IN A $j" >>$NAME.zone echo "$ARPA_IP2 IN PTR $i.$NAME." >>$REV [ $? -eq 0 ]&& echo -e "The $NAME config success:\n$i IN A $j\n$ARPA_IP2 IN PTR $i.$NAME." done else echo "The $FILE List File IS Not Exist .......,Please exit ..." fi fi } ##Define Shell Select Menu PS3="Please select Menu Name Config: " select i in "自动安装Bind服务" "自动初始化Bind配置" "添加解析域名" "批量添加A记录" do case $i in "自动安装Bind服务") Install ;; "自动初始化Bind配置") Init_Config ;; "添加解析域名") Add_named ;; "批量添加A记录") Add_A_List ;; * ) echo ----------------------------------------------------- sleep 1 echo "Please exec: sh $0 { Install(1) or Init_Config(2) or Add_named(3) or Add_config_A(4) }" ;; esac done