前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >每日shell练习题

每日shell练习题

作者头像
老七Linux
发布2018-05-31 10:54:12
4.7K0
发布2018-05-31 10:54:12
举报
文章被收录于专栏:Laoqi's Linux运维专列

(63)需求: –监控节点

一个网站,使用了cdn,全国各地有几十个节点。需要你写一个shell脚本来监控各个节点是否正常。

假如:

代码语言:javascript
复制
#!/bin/bash
url="www.aming.com/index.php"
s_ip="88.88.88.88"
curl -x $s_ip:80 $url > /tmp/source.html 2>/dev/null
for ip in `cat /tmp/ip.txt`
do
    curl -x $ip:80 $url 2>/dev/null >/tmp/$ip.html
    [ -f /tmp/$ip.diff ] && rm -f /tmp/$ip.diff
    touch /tmp/$ip.diff
    diff /tmp/source.html /tmp/$ip.html > /tmp/$ip.diff 2>/dev/null
    n=`wc -l /tmp/$ip.diff|awk '{print $1}'`
    if [ $n -lt 0 ]
    then
        echo "node $ip sth wrong."
    fi
done

(64)需求: –破解字符串

已知下面的字符串是通过RANDOM随机数变量md5sum|cut -c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字。

代码语言:javascript
复制
21029299
00205d1c
a3da1677
1f6d12dd
890684b

解题思路:通过每次传递一个参数的方式,来实现依次破解,$RANDOM的范围为0-32767。

代码语言:javascript
复制
#! /bin/bash

##get the true number via the md5 number.
##written by zhdya_20171010

for n in `seq 0 32767`
do
	a=`echo $n |md5sum | cut -c 1-8`
	for m in `cat /tmp/md5.txt`
	do
		if [ "$m" == "$a" ]
		then
			echo "for the $m, the true number is $n"
		fi
	done
done

-----------------------------------------
运行结果如下:
(4个结果的原因,是其中一个md5只有7为,我们破解匹配的是8位。)
[[email protected] sbin]# sh crackmd5.sh 
for the 00205d1c, the true number is 1346
for the 1f6d12dd, the true number is 7041
for the a3da1677, the true number is 25345
for the 21029299, the true number is 25667

(65)需求: –判断cpu厂商

写一个脚本: 判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。 如果其生产商为AuthenticAMD,就显示其为AMD公司; 如果其生产商为GenuineIntel,就显示其为Intel公司; 否则,就说其为非主流公司。

代码语言:javascript
复制
#! /bin/bash

##judge your computer's cpu.
##written by zhdya_20171011

cpu=`cat /proc/cpuinfo | grep vendor | awk '{print $3}'`

case $cpu in

GenuineIntel)
	echo "This $cpu made from Inter company."
	;;
AuthenticAMD)
	echo "This $cpu made from AMD company."
	;;
*)
	echo "this $cpu made from uncommon company."
	;;
esac

(66)需求: –获取子进程

说明:本shell题目是一个网友在公众号中提问的,正好利用这个每日习题的机会拿出来让大家一起做一做。

给出一个进程PID,打印出该进程下面的子进程以及子进程下面的所有子进程。(只需要考虑子进程的子进程,再往深层次则不考虑)

代码语言:javascript
复制
一条命令查询的方法是:pstree -p pid

(67)需求: –自动添加项目

需求背景:

服务器上,跑的lamp环境,上面有很多客户的项目,每个项目就是一个网站。 由于客户在不断增加,每次增加一个客户(自动创建密码),就需要配置相应的mysql、ftp以及httpd. 这种工作是重复性非常强的,所以用脚本实现非常合适。

mysql增加的是对应客户项目的数据库、用户、密码,ftp增加的是对应项目的用户、密码(使用vsftpd,虚拟用户模式),httpd就是要增加虚拟主机配置段。


首先需要一个基础的nginx虚拟主机配置文件, 一般情况下,我们配置虚拟主机都是建一个vhost目录, 这里我在 /usr/local/nginx/conf/vhost 下面建了一个dd.conf文件

代码语言:javascript
复制
server
{
    listen 80;  
    server_name #host#;
    index index.html index.htm index.php;
    root /data/wwwroot/#host#;

##add php jiexi
location ~ \.php$
      {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/#host#.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/#host#$fastcgi_script_name;
      }
}

绞尽脑汁也没有找出来如何能够添加一个新的虚拟机配置文件,在网上找到了灵感!(感谢度娘+1)

在 /usr/local/php-fpm/etc 下面建了一个pp.conf文件

代码语言:javascript
复制
[[email protected] etc]# cat pp.conf 
[#php#]
listen = /tmp/#php#.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 50
rlimit_files = 1024

在 /etc/vsftpd/vsftpd_user_conf/ 下面建了一个ftpuser文件

代码语言:javascript
复制
[[email protected] vsftpd_user_conf]# cat ftpuser 
local_root=/home/ftpuser/#ftpuser#
anonymous_enable=NO    
write_enable=YES      
local_umask=022     
anon_upload_enable=NO      
anon_mkdir_write_enable=NO    
idle_session_timeout=600   
data_connection_timeout=120    
max_clients=10

注意里面一些关键路径,我用特殊字符组合来表示,这样方便我们添加虚拟注意的时候进行匹配替换。


lnmpvhost.sh 脚本如下:

一定要先满足如下条件:

代码语言:javascript
复制
关闭iptables 以及selinux

yum install -y expect
代码语言:javascript
复制
#! /bin/bash

##add a new vhost and mysql and ftp(before use this shell script, pls it must stop firewall and selinux services!!)
##written by zhdya_20171016

date=`date +%F_%T`
dd="/usr/local/nginx/conf/vhost/dd.conf"
vhost="/usr/local/nginx/conf/vhost"
host="/data/wwwroot"

##create web's dir and configure nginx and php.
read -p "pls input website like "www.baidu.com": " web

if [ -d $host/$web ]
then
	echo "[warning] The $host/$web already exist, pls check it now!"
	exit
else
	mkdir -p $host/$web
	chmod 755 $host/$web
	cat $dd | sed -e "s:#hosts#:${web}:g"|sed -e "s/#host#/${web}/g" > $vhost/$web.conf
	/usr/sbin/nginx -s reload
	cat /usr/local/php-fpm/etc/pp.conf | sed -e "s:#php#:${web}:g"|sed -e "s/#php#/${web}/g" >> /usr/local/php-fpm/etc/php-fpm.conf
	/etc/init.d/php-fpm reload
	echo "already create the $host/$web, and configure php-fpm, nginx success, pls check it!"
fi

##add a user and check the user already exist or not, and add a new ftp user with password!!
read -p "pls input a user: " u
if cat /etc/passwd | awk -F ':' '{print $1}' |grep "$u"
then
	echo "the user already exist."
else
	m=`mkpasswd -l 10 -c 2 -C 2 -d 2`
	useradd $u
	echo "$m" | passwd --stdin $u >/dev/null 2>&1
	echo "$date  username: $u password: $m" >> /tmp/users.txt
	echo "pls check the user's list file."
	read -p "do you need create ftp also? [y/n] " f
		case $f in
		y|yes)
			echo -e "$u\n$m" >> /etc/vsftpd/vsftpd_login
			cat /etc/vsftpd/vsftpd_user_conf/ftpuser | sed -e "s:#ftpuser#:${u}:g"|sed -e "s/#ftpuser#/${u}/g" > /etc/vsftpd/vsftpd_user_conf/$u
			mkdir -p /home/ftpuser/$u
			touch /home/ftpuser/$u/$u.txt
			chown -R $u.$u /home/ftpuser/$u
		;;
		n|no)
		echo "you choice no need to create, exit..."
		break
		;;
		*)
		echo "you input was wrong, pls check it!"
		break
		;;
		esac 
fi 

##create a new database
read -p "do you need create a new database for this new vhost? [y/n] " d
	case $d in
	y|yes)
		read -p "please input database:" database
		read -p "please input dbuser:" dbuser
		read -p "please input dbpwd:" dbpwd
		HOSTNAME="127.0.0.1"
		PORT="3306"
		USERNAME="root"
		read -p "input root pwd:" PASSWORD
		
		create_db_sql="create database ${database}"
                mysql -h${HOSTNAME}  -P${PORT}  -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}"
                if [ $? -ne 0 ]
                then
                        echo 'add db error'
                        exit 0
                fi
                sleep 1
		
		create_db_sql="create user $dbuser"
		/usr/local/mysql/bin/mysql -h${HOSTNAME}  -P${PORT}  -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}"
		if [ $? -ne 0 ]
		then
        		echo 'add db user error'
        		exit 0
		fi
		sleep 1
		
		create_db_sql="grant all  on ${database}.* to ${dbuser}@localhost identified by '${dbpwd}'"
		mysql -h${HOSTNAME}  -P${PORT}  -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}"
		if [ $? -ne 0 ]
		then
        		echo 'user to db user error'
        		echo $create_db_sql
		exit 0
		fi
		
		create_db_sql="flush privileges"
		mysql -h${HOSTNAME}  -P${PORT}  -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}"

		echo 'all of things now already done, pls check it!!'
	;;
	n|no)
		echo "ok, finished!! pls check!!"
		exit
	;;
	*)
		echo "you input was wrong, pls check it!"
		break
	;;
	esac

第二种方法:

代码语言:javascript
复制
#!/bin/bash
webdir=/home/wwwroot
ftpudir=/etc/vsftpd/vuuser
mysqlc="/usr/bin/mysql -uroot -xxxxxx"
httpd_config_f="/usr/local/apache2/conf/extra/httpd-vhosts.conf"

add_mysql_user()
{
        mysql_p=`mkpasswd -s 0 -l 12`
        echo "$pro $mysql_p" >/tmp/$pro.txt
        $mysqlc <<EOF
        grant all on $p.* to "$pro"@'127.0.0.1' identified by "$mysql_p";
EOF

}

add_ftp_user()
{
        ftp_p=`mkpasswd -s 0 -l 12`
        echo "$pro" >> /root/login.txt
        echo "$ftp_p" >> /root/login.txt
        db_load -T -t hash -f /root/login.txt  /etc/vsftpd/vsftpd_login.db
        cd $ftpudir
        cp aaa $pro   //这里的aaa是一个文件,是之前的一个项目,可以作为配置模板
        sed -i "s/aaa/$pro/" $pro  //把里面的aaa改为新的项目名字
        /etc/init.d/vsftpd restart
}

config_httpd()
{
        mkdir $webdir/$pro
        chown vsftpd:vsftpd $webdir/$pro
        echo -e "<VirtualHost *:80> \n     DocumentRoot "/home/internet/www/$pro/" \n     ServerName $dom \n    #ServerAlias \n</VirtualHost> " >> $httpd_config_f
        /usr/local/apache2/bin/apachectl graceful
}

read -p "input the project name: " pro
read -p "input the domain: " dom

add_mysql_user
add_ftp_user
config_httpd

(68)需求: –计算器

用shell写一个简易计算器,可以实现加、减、乘、除运算,假如脚本名字为1.sh,执行示例:./1.sh 1 + 2

代码语言:javascript
复制
#! /bin/bash

##make a simple calculator.
##written by zhdya_20171017

if [ $# -ne "3" ] || [ -z $1 ]
then
	echo "pls input the PARA. like "./calc.sh 1 + 2 " when you use "*" pls add like "./calc.sh 1 \* 2"!!"
	exit
fi

a=`echo "$1" | sed 's/[0-9]//g' | wc -c`
b=`echo "$3" | sed 's/[0-9]//g' | wc -c`

if [ $a -ne 1 ] || [ $b -ne 1 ]
then
	echo "pls just input a number!!"
else
	case "$2" in
	+)
		plus=`expr $1 + $3`
		echo "$1 + $3 = $plus"
	;;
	-)
		subtract=`expr $1 - $3`
		echo "$1 - $3 = $subtract"
	;;
	/)
                echo "$1 / $3 = `expr $1 / $3`"
        ;;
	\*)
		echo "$1 * $3 = `expr $1 \* $3`"
	;;
	*)
		echo "$2 is not a correct fomate"
	;;
	esac
fi

(69)需求: –判断没有文件

判断所给目录内哪些二级目录下没有text.txt文件。 有text.txt文件的二级目录,根据文件计算选项中单词数最大的值(选项间以|分割,单词间以空格分隔)。 假如脚本名字为1.sh, 运行脚本的格式为 ./1.sh 123 root,对于有test.txt的目录,计算出该test.txt文件里面所给出单词的次数。

代码语言:javascript
复制
#!/bin/bash
if [ $# -ne 2 ]
then
    echo "useage $0 dir word"
    exit 1
fi
if [ -d $1 ]
then
    cd $1
else
    echo "$1目录不存在"
    exit 1
fi
for f in `ls $1`
do
    if [ -d $f ]
    then
    if [ -f $f/test.txt ]
    then
        n=`grep -cw "$2" $f/test.txt`
        echo "$1/$f/test.txt 里面有$n个$2"
    else
        echo "$1/$f 下面没有test.txt"
        fi
    fi
done

(70)需求: –打印正方形

代码语言:javascript
复制
交互式脚本,根据提示,需要用户输入一个数字作为参数,最终打印出一个正方形。
在这里我提供一个linux下面的特殊字符■,可以直接打印出来。

示例: 如果用户输入数字为5,则最终显示的效果为
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
代码语言:javascript
复制
#! /bin/bash

##printing a graphic when you type a number.
##written by zhdya_20171019

read -p "pls input a number which you want to printing: " a

ch=`echo "$a" | sed 's/[0-9]//g'|wc -c`

if [ -z $a ] || [ $ch -ne "1" ]
then
	echo "pls just input a number and it's can't run without PARA."
	exit
fi

for m in `seq 1 $a`
do
	for n in `seq 1 $a`
	do
		echo -n "■ "
	done
	echo
done

(71)需求: –问候用户

写一个脚本,依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么,Hello,root,your UID is 0.

代码语言:javascript
复制
awk -F ':' '{print "Hello,"$1",your uid is "$3.}' /etc/passwd

(72)需求: –按要求处理文本

linux系统 /home目录下有一个文件test.xml,内容如下:

<configuration> <artifactItems> <artifactItem> <groupId>zzz</groupId> <artifactId>aaa</artifactId> </artifactItem> <artifactItem> <groupId>xxx</groupId> <artifactId>yyy</artifactId> </artifactItem> </artifactItems> </configuration>

请写出shell脚本删除文件中的注释部分内容,获取文件中所有artifactItem的内容,并用如下格式逐行输出 artifactItem:groupId:artifactId

分析:这个文件比较特殊,但是却很有规律。注释部分内容其实就是中间的内容,所以我们想办法把这些内容删除掉就ok了。而artifactItem的内容,其实就是获取<artifactItem></artifactItem>中间的内容。然后想办法用提到的格式输出即可。

代码语言:javascript
复制
#!/bin/bash
egrep -v '<!--|-->' 1.txt |tee 2.txt  //这行就是删除掉注释的行
grep -n 'artifactItem>' 2.txt |awk '{print $1}' |sed 's/://' > /tmp/line_number.txt
n=`wc -l /tmp/line_number.txt|awk '{print $1}'`

get_value(){
    sed -n "$1,$2"p 2.txt|awk -F '<' '{print $2}'|awk -F '>' '{print $1,$2}' > /tmp/value.txt
    nu=`wc -l /tmp/value.txt|awk '{print $1}'`
    for i in `seq 1 $nu`
    do
        x=`sed -n "$i"p /tmp/value.txt|awk '{print $1}'`
        y=`sed -n "$i"p /tmp/value.txt|awk '{print $2}'`
        echo artifactItem:$x:$y
    done
}

n2=$[$n/2]

for j in `seq 1 $n2`
do
    m1=$[$j*2-1]
    m2=$[$j*2]
    nu1=`sed -n "$m1"p /tmp/line_number.txt`
    nu2=`sed -n "$m2"p /tmp/line_number.txt`
    nu3=$[$nu1+1]
    nu4=$[$nu2-1]
    get_value $nu3 $nu4
done
代码语言:javascript
复制
#! /bin/bash

##delete some special words and print the important infor we needs.
##written by zhdya_20171024

egrep -v '<!--|-->' tt.txt > /tmp/tt1.txt

ar=`sed -n '/<artifactId>/p' /tmp/tt1.txt | sed 's/<artifactId>//g'|sed 's/<\/artifactId>//g'`

for i in $ar
do
	echo "For the artifactId the Value is: $i"
done

gr=`sed -n '/<groupId>/p' /tmp/tt1.txt | sed 's/<groupId>//g'|sed 's/<\/groupId>//g'`

for n in $gr
do
	echo "For the groupId the Value is: $n"
done

(73)需求: –批量杀进程

代码语言:javascript
复制
linux系统中,根目录/root/下有一个文件ip-pwd.ini,内容如下
10.111.11.1,root,xyxyxy
10.111.11.1,root,xzxzxz
10.111.11.1,root,123456
10.111.11.1,root,xxxxxx
……

文件中每一行的格式都为linux服务器的ip,root用户名,root密码,请用一个shell批量将这些服务器中的所有tomcat进程kill掉。

讲解: 有了ip,用户名和密码,剩下的就是登录机器,然后执行命令了。批量登录机器,并执行命令,咱们课程当中有讲过一个expect脚本。所以本题就是需要这个东西来完成。

代码语言:javascript
复制
首先编辑expect脚本 kill_tomcat.expect

#!/usr/bin/expect
set passwd [lindex $argv 0]
set host [lindex $argv 1]
spawn ssh [email protected]$host
expect {
    "yes/no" { send "yes\r"; exp_continue}
    "password:" { send "$passwd\r" }
}
expect "]*"
send "killall java\r"
expect "]*"
send "exit\r"


编辑完后需要给这个文件执行权限 
chmod a+x kill_tomcat.expect

然后编辑shell脚本

#!/bin/bash
n=`wc -l ip-pwd.ini`
for i in `seq 1 $n`
do
    ip=`sed -n "$n"p ip-pwd.ini |awk -F ',' '{print $1}'`
    pw=`sed -n "$n"p ip-pwd.ini |awk -F ',' '{print $3}'`
    ./kill_tomcat.expect $pw $ip
done

(74)需求: –判断函数

请使用条件函数if撰写一个shell函数 函数名为 f_judge,实现以下功能

1)当/home/log 目录存在时 将/home目录下所有tmp开头的文件或目录移/home/log 目录。

2)当/home/log目录不存在时,创建该目录,然后退出。

代码语言:javascript
复制
#! /bin/bash

##judge the dir if exist or not
##written by zhdya_20171025

f_judge()
{
	 find /home -name "tmp*" -exec mv {} /home/log/ \;
}

if [ -d /home/log ]
then
	f_judge
else
	mkdir -p /home/log
	exit
fi

(75)需求: –处理日志

写一个脚本查找/data/log目录下,最后创建时间是3天前,后缀是*.log的文件,打包后发送至192.168.1.2服务上的/data/log下,并删除原始.log文件,仅保留打包后的文件。

代码语言:javascript
复制
#!/bin/bash
find /data/log -name “*.log” -mtime +3 > /tmp/file.list
cd /data/log
tar czvf log.tar.gz `cat /tmp/file.list|xargs`
rsync -a log.tar.gz  192.168.1.2:/data/log  //这一步需要提前做一个免密码登录
for f in `cat /tmp/file.list`
do
    rm -f $f
done

(76)需求: –处理日志

代码语言:javascript
复制
有如下文本,其中前5行内容为
1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123

用shell脚本处理后,按下面格式输出:
[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123
代码语言:javascript
复制
#! /bin/bash
sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt
for id in `cat id.txt`; do
        echo "[$id]"
        awk -v id2=$id -F ':' '$1==id2 {print $2}' filename  // 另外的方式为: awk -F ':' '$1=="'id'" {print $2}' filename  
done

(77)需求: –清日志

要求:两类机器一共300多台,写个脚本自动清理这两类机器里面的日志文件。在堡垒机批量发布,也要批量发布到crontab里面。

A类机器日志存放路径很统一,B类机器日志存放路径需要用匹配(因为这个目录里除了日志外,还有其他文件,不能删除。匹配的时候可用.log)

A类:/opt/cloud/log/ 删除7天前的 B类: /opt/cloud/instances/ 删除15天前的

要求写在一个脚本里面。不用考虑堡垒机上的操作,只需要写出shell脚本。

代码语言:javascript
复制
#!/bin/bash
dir1=/opt/cloud/instances/ 
dir2=/opt/cloud/log/
  if [ -d $dir1 ];then
      find $dir1 -type f -name "*.log" -mtime +15 |xargs rm -f
  elif [ -d $dir2 ];then
      find $dir2 -type f -mtime +7 |xargs rm -f
fi

(78)需求: –贷款计算器

代码语言:javascript
复制
等额本息每月还款额的计算公式是:

[贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]
代码语言:javascript
复制
#! /bin/bash

##calc how much money we should pay.
##written by zhdya_20171031

read -p "pls input how much money you borrow: " b
read -p "pls input how many month you choice: " m
read -p "pls input what's the interest rate "%": " l

if [ -z $b ] && [ -z $m ] && [ -z $l ]
then
	echo "pls you must type a number!!"
	exit
fi

b1=`echo "$l"|sed 's/[0-9.]//g'|wc -c`
m1=`echo "$m"|sed 's/[0-9.]//g'|wc -c`
l1=`echo "$l"|sed 's/[0-9.]//g'|wc -c`

if [ $b1 -ne "1" ] || [ $m1 -ne "1" ] || [ $l1 -ne "1" ]
then
	echo "pls just inpute a number"
	exit
fi

l2=`awk -v x=$l -v y=100 'BEGIN{printf "%.3f\n",x/y}'`  

pay2=`awk -v x=1 -v y=$l2 'BEGIN{printf "%.3f\n",x+y}'`
pay3=`awk -v x=$pay2 -v y=$m 'BEGIN{printf "%.3f\n",x^y}'`
pay5=`awk -v x=$pay3 -v y=1 'BEGIN{printf "%.3f\n",x-y}'`

payy=`awk -v a=$b -v b=$l2 -v c=$pay3 -v d=$pay5 'BEGIN{printf "%.3f\n",a*b*c/d}'`

echo "for per month, you should pay $payy"

第二种方法:

代码语言:javascript
复制
#!/bin/bash
# Author: Maria.(12期-马黎阳)
# Date & Time: 2016-03-07 09:04:01
# Description: 贷款计算器.

read -p "请输入贷款总额(单位:万元):" dkzewy
read -p "请输入贷款年利率(如年利率为6.5%,直接输入6.5):" dknll
read -p "请输入贷款年限(单位:年):" dknx
echo "贷款计算方式:"
echo "1)等额本金计算法"
echo "2)等额本息计算法"
read -p "请选择贷款方式(1|2)" dkfs
dkze=`echo "scale=2;$dkzewy*10000 " | bc -l`
dkll=`echo "scale=6;$dknll/100 " | bc -l`
dkyll=`echo "scale=6;$dkll/12 " | bc -l`
dkqc=$[$dknx*12]

echo "期次 本月还款额 本月利息 未还款额"
debjjsf()
{
    yhbj=`echo "scale=2;($dkze/$dkqc)/1 " | bc -l`
    whbj=$dkze
    for((i=1;i<=$dkqc;i++))
    do
        bylx=`echo "scale=2;($whbj*$dkyll)/1 " | bc -l`
        bybx=`echo "scale=2;($yhbj+$bylx)/1 " | bc -l`
        yhke=`echo "scale=2;($yhbj*$i)/1 " | bc -l`
        whbj=`echo "$dkze-$yhke " | bc -l`
        if [ $i -eq $dkqc ]
        then
            yhbj=`echo "scale=2;($yhbj+$whbj)/1 " | bc -l`
            whbj="0.00"
            bybx=`echo "scale=2;($yhbj+$bylx)/1 " | bc -l`
        fi
        echo "$i $bybx $bylx $whbj"
    done
}

debxjsf()
{
    bybx=`echo "scale=2;(($dkze*$dkyll*((1+$dkyll)^$dkqc))/(((1+$dkyll)^$dkqc)-1))/1 " | bc -l`
    whbj=$dkze
    for((i=1;i<=$dkqc;i++))
    do
        bylx=`echo "scale=2;($whbj*$dkyll)/1 " | bc -l`
        yhbj=`echo "scale=2;($bybx-$bylx)/1 " | bc -l`
        whbj=`echo "scale=2;($whbj-$yhbj)/1 " | bc -l`
        if [ $i -eq $dkqc ]
        then
            bybx=`echo "scale=2;($yhbj+$whbj)/1 " | bc -l`
            whbj="0.00"
        fi
        echo "$i $bybx $bylx $whbj"
    done
}

case $dkfs in
    1) debjjsf
       ;;
    2) debxjsf
       ;;
    *) exit 1
       ;;
esac

(79)需求: –监控磁盘io

阿里云的机器,今天收到客服来的电话,说服务器的磁盘io很重。于是登录到服务器查看,并没有发现问题,所以怀疑是间歇性地。

正要考虑写个脚本的时候,幸运的抓到了一个线索,造成磁盘io很高的幕后黑手是mysql。此时去show processlist,但未发现队列。原来只是一瞬间。

只好继续来写脚本,思路是,每5s检测一次磁盘io,当发现问题去查询mysql的processlist。

帮助:你可以用iostat -x 1 5 来判定磁盘的io,主要看%util

代码语言:javascript
复制
#! /bin/bash

##check the disks IO.
##written by zhdya_20171101

while :
do
    n=`iostat -x 1 5 |tail -n3|head -n1 |awk '{print $NF}'|cut -d. -f1`
    if [ $n -gt 70 ]
    then
        echo "`date` util% is $n%" >>/tmp/mysql_processlist.log
        mysql -uroot -pxxxxxx -e "show  full processlist" >> /tmp/mysql_processlist.log
    fi
    sleep 5
done

(80)需求: –截取tomcat日志

代码语言:javascript
复制
写一个截取tomcat   catalina.out日志的脚本
tomcat实例t1-t4

# tree  -L  1   /opt/TOM/
/opt/TOM/
├── crontabs
├── t1
├── t2
├── t3
└── t4
5 directories, 0 files

# find  /opt/TOM/   -name  catalina.out
/opt/TOM/t1/logs/catalina.out
/opt/TOM/t3/logs/catalina.out
/opt/TOM/t4/logs/catalina.out
/opt/TOM/t2/logs/catalina.out

要求:
1.这个脚本可以取tomcat实例t1-t4的日志
2.这个脚本可以自定义取日志的起始点 ,比如取今天早上10点之后到现在的数据
3.这个脚本可以自定义取日志的起始点和终点,比如取今天早上9点到晚上8点的数据

catalina.out 日志内容

Mar 29, 2016 1:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Mar 29, 2016 1:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Mar 29, 2016 1:52:24 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 2102 ms
代码语言:javascript
复制
#!/bin/bash
##
#Author: 7期孙东
#

export LANG=en_US.UTF-8
export PATH=$PATH
IPADD=`/sbin/ifconfig | grep "inet addr" | head -1 | awk '{print $2}'| awk -F '.' '{print $NF}'`
LOGFILE="/opt/TOM/$1/logs/catalina.out"
YEAR=`date +%Y`
DATE=`date +%m%d_%H%M`
TOMCAT=$1
BEGIN_TIME=$YEAR$2
END_TIME=$YEAR$3
##judge is  a.m.or p.m.
TIME_HOUR1=`echo ${BEGIN_TIME:9:2}`
cut_log() {
        N_DATE1=`echo $1 | sed 's/_/ /g'`
        D_DATE1=`echo $2 | sed 's/_/ /g'`
        E_DATE1=`echo $3 | sed 's/_/ /g'`
        [ $4 ] && N_DATE2=`echo $4 | sed 's/_/ /g'`
        [ $5 ] && D_DATE2=`echo $5 | sed 's/_/ /g'`
        [ $6 ] && E_DATE2=`echo $6 | sed 's/_/ /g'`
                BEGIN=`grep -nE "${N_DATE1}|${D_DATE1}|${E_DATE1}" ${LOGFILE} | head -1 | cut -d : -f1`
                [ "$N_DATE2" ] && END=`grep -nE "${N_DATE2}|${D_DATE2}|${E_DATE2}" ${LOGFILE} | tail -1 | cut -d : -f1`
                [ ! -z "${TIME_HOUR1}" ] && if [ ${TIME_HOUR1} -gt 12 ] ; then
                BEGIN1=`grep -nE "${N_DATE1}|${D_DATE1}|${E_DATE1}" ${LOGFILE} |grep " PM " |grep "${E_DATE1}" | head -1 | cut -d : -f1`
                if [ ! -z "${BEGIN1}" ] ; then
                [ "${BEGIN1}" -gt "${BEGIN}" ] ; BEGIN=${BEGIN1}
                fi
        fi
        if [ "$BEGIN" ] && [ -z "$END" ] ; then
                if [ "$N_DATE2" ]; then
                        echo  "${END_TIME}时间点没有访问日志,请重新设置时间点."
                else
                        sed -n "${BEGIN},[        DISCUZ_CODE_0        ]quot;p ${LOGFILE} > /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log
                fi
        elif [ "$END" ];then
                [ "$BEGIN" ] || BEGIN=1
                sed -n "${BEGIN},${END}"p ${LOGFILE} > /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log
        else
                [ "$END_TIME" != "$YEAR" ] && echo "该时段 ${BEGIN_TIME}~${END_TIME} 没有日志."
                [ "$END_TIME" = "$YEAR" ] && echo "该时段 ${BEGIN_TIME}~now 没有日志."
        fi
        if [ -s /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log ]; then
                cd /home/gcweb  &&  tar -zcf ${IPADD}_${TOMCAT}_${DATE}.tar.gz ${IPADD}_${TOMCAT}_${DATE}.log
                rm -f /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log
                sz /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.tar.gz
                echo "Success to get logs."
                rm -f /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.tar.gz
        fi
}
get_time() {
        case "$1" in
                4)      
                 N_DATE=`date -d "$2" +"%Y-%m-%d" 2>/dev/null`
                 D_DATE=`date -d "$2" +"%Y/%m/%d" 2>/dev/null`
                 E_DATE=`date -d "$2" +"%h %e,_%Y" 2>/dev/null|sed 's/ /_/g'`
                 echo $N_DATE $D_DATE $E_DATE
                 ;;      
                7)      
                 TIME=`echo $2 | awk -F'_' '{print $1,$2}'`
                 N_DATE=`date -d "$TIME" +"%Y-%m-%d_%H" 2>/dev/null`
                 D_DATE=`date -d "$TIME" +"%Y/%m/%d_%H" 2>/dev/null`
                 E_DATE=`date -d "$TIME" +"%h %e,_%Y %l" 2>/dev/null|sed 's/ /_/g'`
                 echo  "$N_DATE"  "$D_DATE" "$E_DATE"
                ;;
                9)     
                 TIME=`echo $2 | awk -F'_' '{print $1,$2}'`
                 N_DATE=`date -d "$TIME" +"%Y-%m-%d_%H:%M" 2>/dev/null`
                 D_DATE=`date -d "$TIME" +"%Y/%m/%d_%H:%M" 2>/dev/null`
                 E_DATE=`date -d "$TIME" +"%h %e,_%Y %l:%M" 2>/dev/null|sed 's/ /_/g'`
                 echo  "$N_DATE" "$D_DATE" "$E_DATE"
                ;;
                *)      
                 echo 1
                ;;
       esac
}
check_arguments () {
        if [ "$1" == 1 ] || [ -z  "$1" ] ;then
                echo "你输入时间参数的格式无法识别, usage: 0108、0108_10、0108_1020"
                exit 3
        fi
}
check_tomcat () {
        if [ ! -s "${LOGFILE}" ] ;then
          echo "tomcat_name: ${TOMCAT} is not exist"
          echo "you can choose:"
          /bin/ls  /home/gcweb/usr/local/
        fi
        if [ $1 -lt 2 ] || [ ! -s "${LOGFILE}" ];then
                echo "usage: $0 tomcat_name {begin_time|begin_time end_time}"
                exit 2
        fi
}
case "$#" in
    0)
        echo "usage: $0 tomcat_name {begin_time|begin_time end_time}"
        exit 1
        ;;
    1)
        check_tomcat $#
        ;;
    2)
        check_tomcat $#
        len=`echo $2 | awk '{print length($0)}'`
        A_DATE=$(get_time  $len $BEGIN_TIME)
        eval  $( echo $A_DATE |awk '{print "N_DATE="$1,"D_DATE="$2,"E_DATE="$3}')
        check_arguments "${N_DATE}"
        cut_log "${N_DATE}" "${D_DATE}" "${E_DATE}"
        ;;
    3)
        check_tomcat $#
        len1=`echo $2 | awk '{print length($0)}'`
        len2=`echo $3 | awk '{print length($0)}'`
        A_DATE=$(get_time ${len1}  $BEGIN_TIME)
        eval  $( echo $A_DATE |awk '{print "N_DATE1="$1,"D_DATE1="$2,"E_DATE1="$3}')
        check_arguments "${N_DATE1}"
        A_DATE=$(get_time ${len2}  $END_TIME)
        eval  $( echo $A_DATE |awk '{print "N_DATE="$1,"D_DATE="$2,"E_DATE="$3}')
        check_arguments "${N_DATE}"
        cut_log ${N_DATE1} ${D_DATE1} ${E_DATE1} "${N_DATE}" "${D_DATE}" "${E_DATE}"
        ;;
    *)
        echo "usage: $0 tomcat_name {begin_time|begin_time end_time};你使用的参数太多哦."
        ;;
esac

(81)需求: –数组

写一个脚本让用户输入多个城市的名字(可以是中文),要求不少于5个,然后把这些城市存到一个数组里,最后用for循环把它们打印出来。

代码语言:javascript
复制
#! /bin/bash

##input five or more city's name, print it use For Script.
##written by zhdya_20171103

export LANG=zh_CN.UTF8

if [ $# -eq '0' ] || [ $# -lt '5' ]
then
	echo "pls input city's name you want, the number at least 5!"
	exit
fi
 
a=(`echo $*`)

for i in `echo ${a[*]}`
do
	echo "the city you typed is: $i"
done

(82)需求: –批量同步代码

需求背景是:

一个业务,有3台服务器(A,B,C)做负载均衡,由于规模太小目前并未使用专业的自动化运维工具。有新的需求时,开发同事改完代码会把变更上传到其中一台服务器A上。但是其他2台服务器也需要做相同变更。

写一个shell脚本,把A服务器上的变更代码同步到B和C上。

其中,你需要考虑到不需要同步的目录(假如有tmp、upload、logs、caches)

代码语言:javascript
复制
#!/bin/bash
echo "该脚本将会把A机器上的/data/wwwroot/www.aaa.com目录同步到B,C机器上";
read -p "是否要继续?(y|n) "
rs() {
    rsync -azP \
    --exclude logs \
    --exclude upload \
    --exclude caches \
    --exclude tmp \
www.aaa.com/ $1:/data/wwwroot/www.aaa.com/
}
if [ $REPLY == 'y' -o $REPLY == 'Y' ]
then
    echo "即将同步……"
    sleep 2
    cd /data/wwwroot/
    rs B机器ip
    rs C机器ip
    echo "同步完成。"
    
elif [ $REPLY == 'n' -o $REPLY == 'N' ]
then
    exit 1
else
    echo "请输入字母y或者n"
fi

(83)需求: –统计并发量

代码语言:javascript
复制
需求背景:

需要统计网站的并发量,并绘图。

思路: 
1 借助zabbix成图
2 通过统计访问日志每秒的日志条数来判定并发量
3 zabbix获取数据间隔30s

说明: 只需要写出shell脚本即可,不用关心zabbix配置

答案Ⅰ

代码语言:javascript
复制
cat /XXX/XXX/www.okay686.cn.log | awk -F '[' '{print $2}'| awk '{print $1}' | sort -r | uniq -c |sort -n

(84)需求: –关闭服务

在centos7系统里,我们可以使用ntsysv关闭不需要开机启动的服务,当然也可以使用chkconfig工具来实现。

写一个shell脚本,用chkconfig工具把不常用的服务关闭。脚本需要写成交互式的,需要我们给它提供关闭的服务名字。

代码语言:javascript
复制
#! /bin/bash

##turn off the services which start with system.
##written by zhdya_20171108

chkconfig --list | awk '{print $1}' > /tmp/chklist.txt

for i in `cat /tmp/chklist.txt`
do
	echo "$i"
done

read -p "pls check the service , choice which one you prefer to turn off when the system start: " tu

if grep -wq $tu /tmp/chklist.txt; 
then 
	chkconfig $tu off;
	echo "the service $tu already turn off, pls checking~" 
else 
	echo "you type was wrong, pls check it again!"
fi

脚本可优化度比较高,后期有需要再次优化!!

(85)需求: –重启tomcat服务

在生产环境中,经常遇到tomcat无法彻底关闭,也就是说用tomcat自带shutdown.sh脚本无法将java进程完全关掉。所以,需要借助shell脚本,将进程杀死,然后再启动。

写一个shell脚本,实现上述功能。彻底杀死一个进程的命令是 kill -9 pid.

代码语言:javascript
复制
#! /bin/bash

##kill all of Tomcat's service!
##written by zhdya_20171109

read -p "pls input the service which you want to kill: " kp
ps aux | awk '{print $1}'|uniq -c |awk '{print $2}' > /tmp/tompid.txt

if grep -wq $kp /tmp/tompid.txt;
then
	pid=`ps aux | grep $kp |awk '{print $2}'`
	for i in $pid
	do
		kill -9 $i > /dev/null 2>&1
	done
	echo "already killed this $kp service, pls check it now!!"
else
	echo "you input was wrong or this service already died!"
fi

//脚本好几处可以再次优化(例如:判断输入的service是不是合法的;判断哪些是系统程序哪些是第三方service!)

(86)需求: –自动增加公钥

写一个shell脚本,当我们执行时,提示要输入对方的ip和root密码,然后可以自动把本机的公钥增加到对方机器上,从而实现密钥认证。

代码语言:javascript
复制
#!/bin/bash
read -p "Input IP: " ip
ping $ip -w 2 -c 2 >> /dev/null
## 查看ip是否可用
while [ $? -ne 0 ]
do
read -p "your ip may not useable, Please Input your IP: " ip
ping $ip -w 2 -c 2 >> /dev/null
done
read -p "Input root\'s password of this host: " password
## 检查命令子函数
check_ok() {
if [ $? != 0 ]
then
echo "Error!."
exit 1
fi
}
## yum需要用到的包
myyum() {
if ! rpm -qa |grep -q "$1"
then
yum install -y $1
check_ok
else
echo $1  already installed
fi
}
for p in openssh-clients openssh expect
do
myyum $p
done
## 在主机A上创建密钥对
if [ ! -f ~/.ssh/id_rsa ] || [ ! -f ~/.ssh/id_rsa.pub ]
then
    if [ -d ~/.ssh ]
    then
        mv ~/.ssh/  ~/.ssh_old
    fi
    echo -e "\n" | ssh-keygen -t rsa -P ''
    check_ok
fi
## 传私钥给主机B
if [ ! -d /usr/local/sbin/rsync_keys ]
then
    mkdir /usr/local/sbin/rsync_keys
fi
cd /usr/local/sbin/rsync_keys
if [ -f rsync.expect ]
then
    d=`date +%F-%T`
    mv rsync.expect $d.expect
fi
#创建远程同步的expect文件
cat >  rsync.expect <<EOF
#!/usr/bin/expect
set host [lindex \$argv 0]
#主机B的密码
set passwd [lindex \$argv 1]
spawn rsync -av /root/.ssh/id_rsa.pub [email protected]\$host:/tmp/tmp.txt
expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "\$passwd\r" }
}
expect eof
spawn ssh [email protected]\$host
expect {
"password:" { send "\$passwd\r" }
}
expect "]*"                         
send "\[ -f /root/.ssh/authorized_keys \] && cat /tmp/tmp.txt >>/root/.ssh/authorized_keys \r"
expect "]*"
send "\[ -f /root/.ssh/authorized_keys \] || mkdir -p /root/.ssh/ \r"            
send "\[ -f /root/.ssh/authorized_keys \] || mv /tmp/tmp.txt /root/.ssh/authorized_keys\r"            
expect "]*"
send "chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys\r"
expect "]*"
send "exit\r"
EOF
check_ok
/usr/bin/expect /usr/local/sbin/rsync_keys/rsync.expect $ip $password
echo "OK,this script is successful. ssh $ip  to test it"

(87)需求: –部署mysql主从

用shell脚本实现,部署mysql主从架构。

思路是这样的:

1)master.sh脚本用来安装master的mysql

2)然后通过expect脚本+rsync工具把slave.sh脚本、/etc/my.cnf、 /etc/init.d/mysqld 还有mysqldump下来的all.sql,以及在master下载下来的mysql二进制安装包传到slave上

3)通过expect脚本来运行slave.sh的脚本来安装,并且配置好主从,期间,用slave.tmp来记录master机子的binlog的状态,以便于传到slave后用命令添加进去。

代码语言:javascript
复制
cp_slave.expect
#!/usr/bin/expect
set user [lindex $argv 0]
set host [lindex $argv 1]
set passwd [lindex $argv 2]
set file [lindex $argv 3]
spawn rsync -avzP $file $user@$host:/tmp
set timeout 600
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof

ins_rsync.expect
#!/usr/bin/expect
set user [lindex $argv 0]
set host [lindex $argv 1]
set passwd [lindex $argv 2]
spawn ssh $user@$host
expect {
 "yes/no" { send "yes\r";exp_continue}
 "password:" { send "$passwd\r" }
}
expect "]*"
send "yum install -y rsync\rexit\r"
interact

slave.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd [lindex $argv 1]
set cm [lindex $argv 2]
spawn ssh [email protected]$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\rexit\r"
interact

slave.sh
#!/bin/bash
####this is for building slave script
##by lv.
####master ip address
mas_ip=192.168.47.24
###mysql password conf
my_passwd=hd8832508
####replication user and password
rp_user=hd
rp_passwd=hd8832508
###check ok
check(){
  if [ $? != 0 ]
  then
     echo "error,please check log."
     exit 1
  fi
}
##close seliux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
selinux_s=`getenforce`
if [ $selinux_s == "Enforcing"  -o $selinux_s == "enforcing" ]
then
    setenforce 0
fi
##close iptables
iptables-save > /etc/sysconfig/iptables_`date +%s`
iptables -F
service iptables save
##install the mirror.aliyun.com
cd /etc/yum.repos.d/
  if rpm -qa |grep epel-release >/dev/null
  then
    rpm -e epel-release
   fi
if [ -f epel.repo ]
then
  /bin/mv epel.repo epel.repo.bak
fi
yum install -y wget
  if [ -f CentOS-Base.repo ]
   then
    /bin/mv CentOS-Base.repo CentOS-Base.repo.bak
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
     wget http://mirrors.aliyun.com/repo/epel-6.repo -O /etc/yum.repos.d/epel.repo
  fi
yum clean all
yum makecache
#first to update datetime
[ `rpm -qa |grep ntpdate|wc -l` -eq 1 ] || yum install -y ntpdate
ntpdate 0.openwrt.pool.ntp.org 2>&1 >/dev/null;clock -w
###install lib software
syum(){
  if ! rpm -qa|grep -q $1
    then
      yum install -y $1
     check
  else
    echo "$1 is already installed"
fi
}
## install some packges for the first on setup.
for p in gcc perl perl-devel libaio libaio-devel pcre-devel zlib-devel cmake glibc pcre compat-libstdc++-33
do
   syum $p
done
###check file is already in tmp 
if [ ! -f /tmp/my.cnf ] && [ ! -f /tmp/mysqld ] && [ ! -f /tmp/mysql-* ] && [ ! -f /tmp/slave.tmp ]
then
   echo "error,please try to sync again"
   exit 1
fi
mysql=`ls /tmp |grep tar.gz`
version=`echo /tmp/$mysql|awk -F - '{print $2}'|cut -d. -f2`
######install mysql
cd /tmp
tar -zxf $mysql
mv `echo $mysql|sed 's/.tar.gz//g'` /usr/local/mysql
cd /usr/local/mysql
if ! grep "^mysql:" /etc/passwd
then
   useradd -s /sbin/nologin -M mysql
   check
fi
[ -d /data/mysql ] && /bin/mv /data/mysql /data/mysql_`date +%s`
mkdir -p /data/mysql
chown -R mysql:mysql /data/mysql
###initialize
case $version in
      1)
    /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/data/mysql
     check
     sed -i '/^server-id/'d /tmp/my.cnf
     check
     sed -i '/\[mysqld\]/a\server-id=2' /tmp/my.cnf
     check
     ;;
     6)
     /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/data/mysql
      check
     sed -i '/^server_id/'d /tmp/my.cnf
     check
     sed -i '/\[mysqld\]/a\server_id = 2' /tmp/my.cnf
     check
      ;;
     7)
      pswd5_7=`/usr/local/mysql/bin/mysqld --user=mysql --datadir=/data/mysql --initialize 2>&1 |sed -r -n '/localhost: /p'|sed 's/.* //g'`
     /usr/local/mysql/bin/mysql_ssl_rsa_setup --datadir=/data/mysql
     check
     sed -i '/^server_id/'d /tmp/my.cnf
     check
     sed -i '/\[mysqld\]/a\server_id = 2' /tmp/my.cnf
     check
     ;;
  esac
###cp conf file
/bin/cp -rf /tmp/my.cnf /etc/my.cnf
check
/bin/cp -rf /tmp/mysqld /etc/init.d/
check
chmod 755 /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
service mysqld start
check
####change mysql password
if [ $version -eq 7 ]
then
    /usr/local/mysql/bin/mysql -uroot -p$pswd5_7 --connect-expired-password -e "set password=password('$my_passwd');"
    check
else
   /usr/local/mysql/bin/mysql -uroot -e "set password=password('$my_passwd');"
   check
fi
###input date
if [ -f /tmp/all.sql ]
then
   /usr/local/mysql/bin/mysql -uroot -p$my_passwd < /tmp/all.sql
   check
else
   echo "date error."
   exit 1
fi
######binlog
slave_bin=`grep "mysql-bin" /tmp/slave.tmp`
slave_pos=`grep '^[0-9]' /tmp/slave.tmp`
###stop slave
/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "stop slave;"
check
###configure slave
/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "change master to master_host='$mas_ip',master_port=3306,master_user='$rp_user',master_password='$rp_passwd',master_log_file='$slave_bin',master_log_pos=$slave_pos;"
check
###start slave
/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "start slave;"
check
###check repecation status
show=`/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "show slave status\G;"|grep 'Slave_IO_Running:'`
slaveIO=`echo $show|awk -F':' '{print $2}'`
Slave_SQL=`echo $show|awk -F':' '{print $2}'`

if [ $slaveIO == Yes ] && [$Slave_SQL == Yes ]
then
  echo "mysql repliation is start"
  /bin/rm -rf /tmp/all.sql /tmp/$mysql /tmp/mysqld /tmp/my.cnf /tmp/slave.tmp
else
  echo "error,please check the log."
fi
master.sh
#!/bin/bash
#####this is building mysql replication###
##by lv.
ml=`pwd`
ar=`arch`
###mysql password conf
my_passwd=hd8832508
####replication user and password
rp_user=hd
rp_passwd=hd8832508
###slave conf
s_user=root
s_host=192.168.47.25
s_passwd=hd8832508
###check ok
check(){
  if [ $? != 0 ]
  then
     echo "error,please check log."
     exit 1
  fi
}
####check the file is exist
for wj in $ml/cp_slave.expect $ml/ins_rsync.expect $ml/slave.expect $ml/slave.sh
do
   if [ ! -f $wj ]
   then
    echo "error,your miss $wj file."
    exit 1
   else
     /bin/chmod +x $wj
     check
   fi
done
##close seliux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
selinux_s=`getenforce`
if [ $selinux_s == "Enforcing"  -o $selinux_s == "enforcing" ]
then
    setenforce 0
fi
##close iptables
iptables-save > /etc/sysconfig/iptables_`date +%s`
iptables -F
service iptables save
##install the mirror.aliyun.com
aliyun(){
cd /etc/yum.repos.d/
  if rpm -qa |grep epel-release >/dev/null
  then
    rpm -e epel-release
   fi
if [ -f epel.repo ]
then
  /bin/mv epel.repo epel.repo.bak
fi
  yum install -y wget
  if [ -f CentOS-Base.repo ]
   then
    /bin/mv CentOS-Base.repo CentOS-Base.repo.bak
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
     wget http://mirrors.aliyun.com/repo/epel-6.repo -O /etc/yum.repos.d/epel.repo
  fi
yum clean all
yum makecache
}
if [ `grep "aliyun.com" /etc/yum.repos.d/CentOS-Base.repo|wc -l` -eq 0 ]
then
   aliyun
else
   echo "aliyun epel is already installed."
fi 
#first to update datetime
[ `rpm -qa |grep ntpdate|wc -l` -eq 1 ] || yum install -y ntpdate
ntpdate 0.openwrt.pool.ntp.org 2>&1 >/dev/null;clock -w
###install lib software
syum(){
  if ! rpm -qa|grep -q $1
    then
      yum install -y $1
     check
  else
    echo "$1 is already installed"  
fi
}
## install some packges for the first on setup.
for p in gcc perl perl-devel libaio libaio-devel pcre-devel zlib-devel cmake glibc pcre compat-libstdc++-33
do
   syum $p
done
###variables,fuctions
mysql_5_1=http://mirrors.sohu.com/mysql/MySQL-5.1/mysql-5.1.73-linux-$ar-glibc23.tar.gz
mysql_5_6=http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.31-linux-glibc2.5-$ar.tar.gz
mysql_5_7=http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.12-linux-glibc2.5-$ar.tar.gz
#######################################
conf_mysql(){
   cd /usr/local/mysql
   if ! grep "^mysql:" /etc/passwd
   then
   useradd -s /sbin/nologin -M mysql
   check
   fi
   [ -d /data/mysql ] && /bin/mv /data/mysql /data/mysql_`date +%s`
    mkdir -p /data/mysql
    chown -R mysql:mysql /data/mysql
###initialize
   case $version in
      5.1)
    ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql
     check
     ;;
     5.6)
     ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql
      check
      ;;
     5.7)
      pswd5_7=`./bin/mysqld --user=mysql --datadir=/data/mysql --initialize 2>&1 |sed -r -n '/localhost: /p'|sed 's/.* //g'`
     ./bin/mysql_ssl_rsa_setup --datadir=/data/mysql
     check
     ;;
  esac
}
cp_mysql(){
###my.cnf
      if [ -f  /usr/local/mysql/support-files/my-huge.cnf ]
         then
         /bin/cp -rf support-files/my-huge.cnf /etc/my.cnf
         check
	 sed -i '/^\[mysqld\]$/a\datadir = /data/mysql' /etc/my.cnf
           check
         else
            /bin/cp -rf support-files/my-default.cnf /etc/my.cnf
             check
        sed -i '/^\[mysqld\]$/a\socket = /tmp/mysql.sock' /etc/my.cnf
        sed -i '/^\[mysqld\]$/a\port = 3306' /etc/my.cnf
        sed -i '/^\[mysqld\]$/a\datadir = /data/mysql' /etc/my.cnf
        check
        sed -i '/^\[mysqld\]$/a\basedir = /usr/local/mysql' /etc/my.cnf
        fi
####/etc/init.d/mysqld
     if [ $version == 5.7 ]
     then
      /bin/cp support-files/mysql.server /etc/init.d/mysqld
      check
       sed -i 's#^datadir=#datadir=/data/mysql#' /etc/init.d/mysqld
       sed -i 's#^basedir=#basedir=/usr/local/mysql#' /etc/init.d/mysqld
     check
      chmod 755 /etc/init.d/mysqld
      chkconfig --add mysqld
      chkconfig mysqld on
      service mysqld start
      check
     else
      /bin/cp support-files/mysql.server /etc/init.d/mysqld
      sed -i 's#^datadir=#datadir=/data/mysql#' /etc/init.d/mysqld
      chmod 755 /etc/init.d/mysqld
      chkconfig --add mysqld
      chkconfig mysqld on
      service mysqld start
      check
    fi

}

###install mysql
insall_mysql(){ 
echo "Chose the version of mysql."
select mysql_v in 5.1 5.6 5.7
do
    case $mysql_v in
        5.1)
            cd /usr/local/src
            [ -f ${mysql_5_1##*/} ] || wget $mysql_5_1
            tar zxf ${mysql_5_1##*/}
            check_ok
            [ -d /usr/local/mysql ] && /bin/mv /usr/local/mysql /usr/local/mysql_`date +%s`
            mv `echo ${mysql_5_1##*/}|sed 's/.tar.gz//g'` /usr/local/mysql
            check_ok
           version=5.1
            conf_mysql
            cp_mysql
        break
        ;;
    5.6)
            cd /usr/local/src
            [ -f ${mysql_5_6##*/} ] || wget $mysql_5_6
            tar zxf ${mysql_5_6##*/}
            check_ok
            [ -d /usr/local/mysql ] && /bin/mv /usr/local/mysql /usr/local/mysql_bak
            mv `echo ${mysql_5_6##*/}|sed 's/.tar.gz//g'` /usr/local/mysql
        check_ok
            version=5.6
            conf_mysql
            cp_mysql
        break
        ;;
    5.7)
            cd /usr/local/src
            [ -f ${mysql_5_7##*/} ] || wget $mysql_5_7
            tar zxf ${mysql_5_7##*/}
            check_ok
            [ -d /usr/local/mysql ] && /bin/mv /usr/local/mysql /usr/local/mysql_bak
            mv `echo ${mysql_5_7##*/}|sed 's/.tar.gz//g'` /usr/local/mysql
            check_ok
            version=5.7
           conf_mysql
           cp_mysql
            break
            ;;
    *)
            echo "only 1(5.1) 2(5.6) or 3(5.7) "
            exit 1
            ;;
    esac
done
}
####change mysql password
passwd_mysql(){
if [ $version == 5.7 ]
then
    /usr/local/mysql/bin/mysql -uroot -p$pswd5_7 --connect-expired-password -e "set password=password('$my_passwd');"
    check
else
   /usr/local/mysql/bin/mysql -uroot -e "set password=password('$my_passwd');"
   check
fi
}
######
if [ `ps aux|grep mysql|wc -l` -gt 1 ]
then
   echo "mysql is already start"
else
   insall_mysql
   passwd_mysql
fi
####start install slave
echo "#############################"
echo "##                         ##"
echo "##      slave install      ##"
echo "##                         ##"
echo "#############################"
##first check master tool
if ! rpm -qa|grep -q rsync 
then
  yum install -y rsync
fi
if ! rpm -qa|grep -q expect
then
  yum install -y expect
fi
###replication building for master first
if [ `ps aux|grep mysql|wc -l` -gt 1 ] && [ `grep "log_bin = mysql-bin" /etc/my.cnf|wc -l` -eq 0 ] && [ `grep "log-bin=mysql-bin" /etc/my.cnf|wc -l` -eq 0 ]
then
   /etc/init.d/mysqld stop
   check
   sed -i '/^\[mysqld\]$/a\server_id = 1' /etc/my.cnf
   sed -i '/^\[mysqld\]$/a\log_bin = mysql-bin' /etc/my.cnf
   sed -i '/^\[mysqld\]$/a\binlog_format = "MIXED"' /etc/my.cnf
    check
   /etc/init.d/mysqld start
   check
fi
master_bin=`/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "show master status \G;"|grep File|awk '{print $2}'`
master_pos=`/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "show master status \G;"|grep Position|awk '{print $2}'`
echo $master_bin >>/tmp/slave.tmp
echo $master_pos >>/tmp/slave.tmp
/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "grant replication slave on *.* to $rp_user@'$s_host' identified by '$rp_passwd';"
check
/usr/local/mysql/bin/mysql -uroot -p$my_passwd -e "flush privileges;"
check
###dump date
/usr/local/mysql/bin/mysqldump -uroot -p$my_passwd --single-transaction -A > /tmp/all.sql
check
####cp file to slave
if [ `pwd` != $ml ]
then
   cd $ml
fi
./ins_rsync.expect $s_user $s_host $s_passwd
for file in /usr/local/src/mysql-* /etc/my.cnf /etc/init.d/mysqld ./slave.sh /tmp/slave.tmp /tmp/all.sql
do
   ./cp_slave.expect $s_user $s_host $s_passwd $file
done
./slave.expect $s_host $s_passwd /tmp/slave.sh
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/01/13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档