第六天
一、while
1、范例1:每隔2秒记录一次系统负载情况
1.1 方法一:屏幕输出
[root@node4 day6]# cat while01.sh
#!/bin/bash
while true
do
uptime
sleep 2
done
1.2 追加到log里,使用微秒单位
[root@node4 day6]# cat while02.sh
#!/bin/bash
while [ 1 ]
do
uptime >> ./uptime.log
usleep 1000000
done
[root@node4 day6]# sh while02.sh &
跟踪文件更新和尾部变化:
[root@node4 day6]# tail -f uptime.log
1.3 查看后台执行的任务
[root@node4 day6]# sh while02.sh &
[1] 5355
[root@node4 day6]# jobs
[1]+ Running sh while02.sh &
[root@node4 day6]#
拿到前台:
[root@node4 day6]# fg 1
sh while02.sh
(1)
暂停任务:
Ctrl+z
[1]+ Stopped sh while02.sh
(2)
放到后台执行:
[root@node4 day6]# bg
[1]+ sh while02.sh &
[root@node4 day6]# jobs
[1]+ Running sh while02.sh &
1.4 nohup
2、范例二
2.1 求1到100的和
[root@node4 day6]# cat while03.sh
#!/bin/bash
# xsz
# qq:666
# functions:while-3 example
# version:1.1
i=1
sum=0
while((i<=100))
do
((sum=sum+i))
((i++))
done
[ "$sum" -ne 0 ] && printf "totalsum is:$sum\n"
[root@node4 day6]# sh while03.sh
totalsum is:5050
[root@node4 day6]#
2.2 通过算法实现
[root@node4 day6]# cat sum.sh
#!/bin/sh
i=100
((sum=i*(i+1)/2))
echo $sum
[root@node4 day6]# sh sum.sh
5050
[root@node4 day6]# cat sum2.sh
#!/bin/sh
i=10000000
((sum=i*(1+10000000)/2))
echo $sum
[root@node4 day6]# sh sum2.sh
50000005000000
[root@node4 day6]#
提示:上述公式中an表示等差数列的第N项。
求和公式
Sn=(a1+an)n/2
Sn=a1n+n(n-1)d/2 d=公差
3、范例3:使用while循环竖向打印10,9,8……1
3.1 方法1
[root@node4 day6]# cat while04.sh
#!/bin/sh
i=10
while ((i>0))
do
echo $i
((i--))
done
[root@node4 day6]# sh while04.sh
10
9
8
7
6
5
4
3
2
1
[root@node4 day6]#
3.2 方法二
两个中括号需要用$调用i
[root@node4 day6]# cat while05.sh
#!/bin/sh
i=10
while [[ $i > 0 ]]
do
echo $i
((i--))
done
[root@node4 day6]# sh while05.sh
10
9
8
7
6
5
4
3
2
1
[root@node4 day6]#
3.3 正着打
[root@node4 day6]# cat while06.sh
#!/bin/sh
i=1
while [[ i -lt 11 ]]
do
echo $i
((i++))
done
[root@node4 day6]# sh while06.sh
1
2
3
4
5
6
7
8
9
10
[root@node4 day6]#
3.4 其他
[root@node4 day6]# cat while07.sh
#!/bin/sh
read -t 20 -p "please input ht enumber:" i
while ((i--))
do
echo $i
done
[root@node4 day6]# sh while07.sh
please input ht enumber:11
10
9
8
7
6
5
4
3
2
1
0
[root@node4 day6]#
传参:
[root@node4 day6]# cat while08.sh
#!/bin/sh
i="$1"
while [ $i -gt 0 ]
do
echo $i
((i--))
done
[root@node4 day6]#
[root@node4 day6]# sh while08.sh 5
5
4
3
2
1
[root@node4 day6]#
3.5 until
until先执行循环再判断
[root@node4 day6]# cat until01.sh
#!/bin/sh
i=1
until ((i>100))
do
((sum=sum+i))
((i++))
done
[ -n "$sum" ] && echo $sum
[root@node4 day6]# sh until01.sh
5050
[root@node4 day6]# cat until02.sh
#!/bin/sh
i=10
until [[ $i < 1 ]]
do
echo $i
((i--))
done
[root@node4 day6]# sh until02.sh
10
9
8
7
6
5
4
3
2
1
[root@node4 day6]#
3.6 定时访问网站地址
[root@node4 day6]# cat while09.sh
#!/bin/bash
while true
do
curl -I -s http://www.niaoyun.com | head -1
sleep 10
done
[root@node4 day6]# sh while09.sh
HTTP/1.1 301 Moved Permanently
修改:
[root@node4 day6]# cat while09.sh
#!/bin/bash
while true
do
if [ `curl -o /dev/null -s -w "%{http_code}" http://10.201.106.134` -ne 200 ];then
echo "10.201.106.134 error"
#echo "niaoyun.com is error" | mail -s "18-status" root@localhost
else
echo "10.201.106.34 ok"
fi
sleep 2
done
[root@node4 day6]# sh while09.sh
10.201.106.34 ok
10.201.106.34 ok
10.201.106.34 ok
10.201.106.34 ok
10.201.106.134 error
10.201.106.134 error
10.201.106.134 error
二、高级例子
1、判断URL是否正常的脚本
1.1 方法1 根据http code status判断
[root@node4 day6]# cat while-2-1.sh
#!/bin/sh
while true
do
status=`curl -o /dev/null -s -w "%{http_code}" $1`
if [ "$status" = "200" ];then
echo "this url is good"
else
echo "this url is bad"
fi
sleep 2
done
[root@node4 day6]# sh while-2-1.sh www.baidu.com
this url is good
this url is good
this url is good
函数化:
[root@node4 day6]# cat while-2-1-2.sh
#!/bin/sh
. /etc/init.d/functions
while true
do
status=`curl -o /dev/null -s -w "%{http_code}" $1`
if [ "$status" = "200" ];then
action "this url is good" /bin/true
else
action "this url is bad" /bin/false
fi
sleep 1
done
[root@node4 day6]# sh while-2-1-2.sh www.baidu.com
this url is bad [FAILED]
this url is good [ OK ]
this url is good [ OK ]
this url is good [ OK ]
this url is good [ OK ]
1.2 数组方法检查
失败: [root@node4 day6]# cat while-2-2.sh #!/bin/sh . /etc/init.d/functions
url_list=(
http://www.baidu.com
http://www.qq.com
http://www.niaoyun.com
)
function wait()
{
echo -n "3秒后,执行该操作."
for ((i=0;i<3;i++))
do
echo -n ".";sleep 1
done
}
function check_url()
{
wait
echo 'check url...'
for((i=0;i<`echo ${#url_list[*]}`;i++))
do
#HTTP/1.1 200 OK
#judge=($(curl -I -s ${url_list[$i]} | head -1 | tr "\r" "\n"))
judge=($(curl -o /dev/null -s -w "%{http_code}" "${url_list[$i]}"))
if [[ "${judge[1]}" == '200' || "${judge[2]}" == 'OK' ]];then
action "${url_list[$i]}" /bin/true
else
action "${url_list[$i]}" /bin/false
fi
done
}
check_url
2、apache日志分析
2.1 问题1、计算apache一天的日志access_2010-12-8.log中所有行的日志各元素的访问字节数的总和
取出字节数:
[root@node4 day6]# awk '{print $10}' access_2010-12-8.log | grep -v "-"
44286
10850
11809
255
计算:
[root@node4 day6]# awk '{print $10}' access_2010-12-8.log | grep -v "-" | tr "\n" "+" | sed 's#+$#\n#g' | bc
226905
[root@node4 day6]#
脚本:
[root@node4 gaoji]# cat while05.sh
exec <access_2010-12-8.log
sum=0
while read line
do
[ -z "`echo $line | awk '{print $10}' | sed 's#[0-9]##g'`" ] || continue
((sum=sum+`echo $line | awk '{print $10}'`))
done
echo $sum
[root@node4 gaoji]# sh while05.sh
226905
修改,增加变量:
[root@node4 gaoji]# cat while05.sh
exec <access_2010-12-8.log
sum=0
while read line
do
bytes=`echo $line | awk '{print $10}'`
[ -z "`echo $bytes | sed 's#[0-9]##g'`" ] || continue
((sum=sum+$bytes))
done
echo $sum
for循环:
[root@node4 gaoji]# cat for-6.sh
#!/bin/bash
size=`awk '{print $10}' $1`
sum=0
for num in $size
do
[ -n "$num" -a "$num" = "${num//[^0-9]/}" ] || continue
((sum=$num+sum))
done
echo "Log.size:$sum bytes`echo $(($sum/1024))`KB"
[root@node4 gaoji]# sh for-6.sh access_2010-12-8.log
Log.size:226905 bytes221KB
2.2 抓阄脚本
1)执行脚本后,想去的同学输入英文名全拼,产生随机数01-99之间的数字,数字越大就去参加项目实践,前面已经抓到的数字,下次不能再出现相同数字。
2)第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入。
低配版:输入名字打印名字和一个随机数,然后继续等待输入。
[root@node4 gaoji]# cat while06.sh
#!/bin/sh
while read -p "please input you name: " name
do
if [ -n "$name" ]; then
echo -e "$name\t$RANDOM"
fi
done
[root@node4 gaoji]# sh while06.sh
please input you name: xs
xs 6982
please input you name: xsz
xsz 10364
三、for循环
1、for简单例子
1.1 列出数字
[root@node4 for]# cat for01.sh
#!/bin/sh
for num in 5 4 3 2 1
do
echo $num
done
[root@node4 for]# cat for01.sh
#!/bin/sh
for ip in 10.201.106.1 10.201.106.2
do
ping -c 1 $ip
done
法2:
[root@node4 for]# cat for01.sh
#!/bin/sh
for num in {5..1}
do
echo $num
done
[root@node4 for]# sh for01.sh
5
4
3
2
1
[root@node4 for]# cat for01.sh
#!/bin/sh
for num in `seq 5 -1 1`
do
echo $num
done
打单数:
[root@node4 for]# cat for01.sh
#!/bin/sh
for num in `seq 9 -2 1`
do
echo $num
done
1.2 打印当前目录内容
[root@node4 for]# cat for02.sh
#!/bin/sh
for filename in `ls .`
do
echo $filename
done
1.3 清理开机自启动的服务
[root@node4 for]# cat for03.sh
#!/bin/sh
LANG=en
for oldboy in `chkconfig --list | grep 3:on | awk '{print $1}'`
do
chkconfig --level 3 $oldboy off
done
把需要的服务开启:
[root@node4 for]# cat for03.sh
#!/bin/sh
LANG=en
for oldboy in crond network syslog sshd
do
chkconfig --level 3 $oldboy on
done
1.4 seq
[root@node4 for]# seq 6
1
2
3
4
5
6
[root@node4 for]# seq 3 6
3
4
5
6
[root@node4 for]# seq 1 2 10
1
3
5
7
9
[root@node4 for]# seq -s , 1 10
1,2,3,4,5,6,7,8,9,10
计算
[root@node4 for]# seq -s "+" 5 | bc
15
2、企业面试题
2.1 使用for循环在/oldboy目录下创建10个文件,名称依次为oldboy-1 oldboy-2
[root@node4 for]# cat a1.sh
#!/bin/bash
for file in `seq 10`
do
[ ! -d "$dir" ] && mkdir -p /oldboy
touch /oldboy/oldboy-$file
done
[root@node4 for]# cat a1-2.sh
#!/bin/sh
DIR=/oldboy
mkdir $DIR -p
[ ! -d $dir ] && exit
for num in `seq 10`
do
cd $DIR && touch oldboy-$num
done
2.2 将以上文件中的oldboy全部改成linux
[root@node4 for]# cat a2.sh
for f in `ls /oldboy/*`
do
mv $f `echo $f | sed 's#oldboy-#linux-#g'`
done
[root@node4 for]# cat a2-1.sh
for f in `seq 10`
do
cd /oldboy
mv oldboy-$f linux-$f
done
[root@node4 for]# cat a2-2.sh
#!/bin/bash
DIR=/oldboy
[ ! -d $DIR ] && exit 1
cd $DIR
for f in `ls /oldboy/`
do
mv $f linux-`echo $f | cut -d "-" -f2`
done
2.3 批量创建10个系统账号oldboy01-oldboy10并设置密码(密码不能相同)
[root@node4 for]# cat a3.sh
for n in `seq -w 10`
do
useradd oldboy-$n && echo "oldboy-$n" | passwd --stdin oldboy-$n
done
2.4 批量创建10个系统账号oldboy01-oldboy10并设置密码(密码为随机8位数)
[root@node4 for]# cat a4.sh
for n in `seq -w 11 15`
do
useradd oldboy-$n
pass=`echo $RANDOM | md5sum | cut -c 11-18`
echo -e "user:oldboy-$n pass:$pass" >> /tmp/user.log
echo "$pass" | passwd --stdin oldboy-$n
done
[root@node4 for]# cat /tmp/user.log
user:oldboy-11 pass:8705147a
user:oldboy-12 pass:f6816151
user:oldboy-13 pass:561cf29e
user:oldboy-14 pass:d38ad8a6
user:oldboy-15 pass:5c60ead2
3、MySQL分表分库备份
3.1 分库备份
[root@node4 for]# cat mysql_bak.sh
#!/bin/bash
myuser="root"
mypass="oldboy123"
mycmd="mysql -u$myuser -p$mypass"
mydump="mysqldump -u$myuser -p$mypass"
for database in oldboy hellodb zabbix
do
$mydump $database | gzip > /backup/${database}_$(date +%F).sql.gz
done
[root@node4 backup]# ls
hellodb_2018-03-05.sql.gz oldboy_2018-03-05.sql.gz zabbix_2018-03-05.sql.gz
备份所有数据库,单库备份:
[root@node4 for]# cat mysql_bak01.sh
#!/bin/bash
myuser="root"
mypass="oldboy123"
mycmd="mysql -u$myuser -p$mypass"
mydump="mysqldump -u$myuser -p$mypass"
for database in `$mycmd -e "SHOW DATABASES;" | sed '1d'`
do
$mydump $database | gzip > /backup/${database}_$(date +%F).sql.gz
done
不备份系统库:
for database in `$mycmd -e "SHOW DATABASES;" | sed '1d' | grep -Ev "mysql|information_schema"`
3.2 分表
[root@node4 for]# cat mysql_bak02.sh
#!/bin/bash
myuser="root"
mypass="oldboy123"
mycmd="mysql -u$myuser -p$mypass"
mydump="mysqldump -u$myuser -p$mypass"
for database in `$mycmd -e "SHOW DATABASES;" | sed '1d' | grep -Ev "mysql|information_schema"`
do
[ ! -d "/backup/${database}" ] && mkdir -p /backup/${database}
for table in `$mycmd -e "SHOW TABLES from $database;" | sed '1d'`
do
$mydump $database $table | gzip > /backup/${database}/${database}_${table}_$(date +%F).sql.gz
done
done
[root@node4 backup]# tree /backup/
/backup/
├── hellodb
│ ├── hellodb_classes_2018-03-05.sql.gz
│ ├── hellodb_coc_2018-03-05.sql.gz
│ ├── hellodb_courses_2018-03-05.sql.gz
│ ├── hellodb_scores_2018-03-05.sql.gz
│ ├── hellodb_students_2018-03-05.sql.gz
│ ├── hellodb_teachers_2018-03-05.sql.gz
│ └── hellodb_toc_2018-03-05.sql.gz
├── oldboy
│ ├── oldboy_kecheng_2018-03-05.sql.gz
│ └── oldboy_student_2018-03-05.sql.gz
├── test
└── zabbix
├── zabbix_agent_2018-03-05.sql.gz
└── zabbix_server_2018-03-05.sql.gz