一、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