目录
例:还是写从1加到100的例子,注意和while循环的区别:
1、for循环
for循环是固定循环,有时也把for循环称为计数循环。
for的语法有如下两种:
1.带列表循环
for 变量 in 值1 值2 值3 .....
do
程序
done
2.类C的for循环
for ((初始值;循环控制条件;变量变化))
do
程序
done
1)语法二中需注意:
初始值:
在循环开始时,需要给某个变量赋予初始值,如i=1
循环控制条件:
用于指定变量循环的次数,如i<=100,则只要i的值小于等于100,循环就会继续。
变量变化:
每次循环之后,变量该如何变化,如i=i+1(i=++i、i++)。代表每次循环之后,变量i的值都加1。
2)语法一举例:
例:打印时间
【】# cat for1.sh
#!/bin/bash
for time in mirning noon afternoon evening
do
echo "This is $time"
done
例:批量解压缩
【】# cat auto-tar.sh
#!/bin/bash
cd /lamp
ls *.tar.gz > ls.log
for i in $(cat ls.log)
do
tar -xvf $i &> /dev/null
done
rm -rf /lamp/ls.log
脚本编写完成后,给脚本执行权限。光盘换成lamp,创建/lamp,把lamp中的内容复制到/lamp中。
2)语法二举例:
例:从1加到100
【】# cat for-1-100.sh
#!/bin/bash
s=0
for ((i=1; i<=100; i=i+1))
do
s=$(($s+$i))
done
echo "The sum of 1+2+....+100 is :$s"
例2:批量添加指定数量的用户
【】# cat useradd.sh
#!/bin/bash
# 批量添加指定数量的用户
# 创建用户默认名
# 创建默认密码。
read -p "Please input user name:" -t 30 name
read -p "Please input the number of users:" -t 30 num
read -p "Please input the password of users:" -t 30 pass
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]
then
y=$(echo $num | sed 's/[0-9]//g')if [ -z "$y"]
then
for (( i=1;i<=$num;i=i+1))
do
/usr/sbin/useradd $name$i &> /dev/null
echo $pass | /usr/bin/passwd --stdin $name$i &> /dev/null
done
fi
fi
例3:批量删除用户
【】# cat userdel.sh
#!/bin/bash
ls /home/ > /tmp/user.txt
user=$(cat /tmp/user.txt)
for i in $user
do
userdel -r $i
done
rm -rf /tmp/user.txt
二、while循环
1.格式1
while [条件判断式]
do
程序
done
对while循环来讲,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立循环才会停止。
【】# cat while.sh
#!/bin/bashi=1
s=0
while [ $i -le 100 ]
do
s=$(( $s+$i))
i=$(( $i+1))
done
echo "the sum si:$s"
2.格式2:
while true
do
command
done
列题:
还可以简单的结合之前重启apache的脚本,进行循环监测apache。
【】# cat autostart.sh
#!/bin/bash
while true
do
port=$(nmap -sT 192.168.22.222 | grep tcp | grep http | awk '{print $2}')
if [ "$port" == "open" ]
then
echo "$(date) httpd is ok!" >> /tmp/autostart-acc.log
else
/etc/rc.d/init.d/httpd start &> /dev/null
echo "$(date) restart httpd!!" >> /tmp/autostart-err.log
fi
sleep 5 #检测的间隔时间为5秒。
done
三、until循环
until循环和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。(当测试结果为假时才继续执行循环体直到测试为真时才停止循环)
until [条件判断式]
do
程序
done
例:还是写从1加到100的例子,注意和while循环的区别:
[root@localhost ~]# cat until.sh
#!/bin/bash
i=1
s=0
until [ $i -gt 100 ]
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "the sum is:$s"
四、函数
在编写脚本时,有些语句会被重复使用多次。把这些可能重复使用的代码写成函数,这样我们通过函数名称可以更高效的重复利用他们。如果想让自己写的脚本代码可以为别人所使用,同样需要函数功能。
function 函数名 () {
程序
}
例:简单的函数示例
#!/bin/bash
function demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
例:我们自己写一个函数,还是之前的从1加到100的循环。但这次我们用函数来实现,不过
不再是从1加到100了,而是让用户自己决定加到多少:
[root@localhost ~]# cat function.sh
#!/bin/bashfunction sum () {
s=0
for (( i=0;i<=$1;i=i+1 ))
do
s=$(( $i+$s ))
done
echo "the sum of 1+2+3+..+$1 is :$s"
}
read -p "please input a number:" num
y=$(echo $num | sed 's/[0-9]//g')
if [ -z "$y" ]
then
sum $num
else
echo "error!!please input a number!"
fi
五、特殊流程控制语句
1.exit语句
系统是有exit命令的,用于退出当前用户的登录状态,可是在shell脚本中,exit语句是用来退出当前脚本的。也就是说在shell脚本中,只要碰到exit语句,后续的程序就不再执行,而直接退出脚本。
exit语法:
exit [返回值]
如果exit命令之后定义了返回值,那么这个脚本执行之后的返回值就是我们自己定义的返回值。可以通过$?查询,来查看返回值,范围是0-255。如果exit之后没有定义返回值,脚本执行之后的返回值是执行exit之前,最后执行一条命令的返回值。
例:
[root@localhost ~]# cat exit.sh
#!/bin/bash
read -t 30 -p "please input a number:" num
y=$(echo $num | sed 's/[0-9]//g')
[ -n "$y" ] && echo "error!please input a number!" && exit 8
echo "the number is:$num"
2.break语句
break概述:
跳出当前整个循环或结束当前循环,在for、while等循环语句中,用于跳出当前所在的循环体,执行循环体之后的语句,后面如果什么也不加,表示跳出当前循环等价于break 1,也可以在后面加数字,假设break 3表示跳出第三层循环
例:
【】# cat break.sh
#!/bin/bash
for ((i=1; i<=10; i=i+1 ))
do
if [ "$i" -eq 4 ]
then
break
fi
echo $i
done
【】# . break.sh
1
2
3
【】#
3.continue语句
continue概述:
忽略本次循环剩余的代码,直接进行下一次循环;在for、while等循环语句中,用于跳出当前所在的循环体,执行循环体之后的语句,如果后面加的数字是1,表示忽略本次条件循环,如果是2的话,忽略下来2次条件的循环还用刚才的脚本,把break换成continue:
【】# cat continue.sh
#!/bin/bash
for ((i=1; i<=10; i=i+1 ))
do
if [ "$i" -eq 4 ]
then
continue #退出语句continue。
fi
echo $i
done
【】# . continue.sh #执行脚本。
1
2
3
5
6
7
8
9
10
#在输出内容里,只是少了4这个数字。其他数字正常输出。
continue只会退出单词循环,所以并不影响后续的循环,结果就是只会少4的输出。两个脚本相比较之下,应该能更清楚说明break和continue的区别。
4.Shift参数左移指令:
作用:每执行一次,参数序列顺次左移一个位置,$#的值减1,用于分别处理每个参数,移出去的参数,不再可用.
例子:加法计算器
【】# cat shift.sh
#!/bin/bash
if [ $# -le 0 ];then
echo “没有足够的参数”
exit
fi
sum=0
while [ $# -gt 0 ] ; do
sum=$[$sum+$1]shift
# shift 2 一次移动2个参数
done
echo result is $sum
测试:
【】# bash a shift.sh 11 2 3 4
result is 20
5.trap命令:
用于指定在接收到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作。
trap -l:查询trap能够接收的信号。
【】# trap "echo 9999999" SIGINT INT
#trap命令格式为:trap "执行动作" SIGINT(检测信号)整体命令为检测到SIGINT信号或INT信号时会去执行echo 999的命令。但是只在命令行中执行可能会遇到的问题是。
trap命令在当前命令生效,而一些比如tail -f /var/log/message命令在子shell生效,所以并不能看到echo 9999的效果。而且,命令行中能够执行的命令有限,通常情况下trap命令会写到脚本中并且"执行动作"会用函数来代替。
例:
【】# cat test.sh
#!/bin/bash
#trap 'mytrap' SIGINT INT #执行动作为函数mytrap,接收信号为SIGINT或INT
#trap 'mytrap' SIGINT #执行动作为函数mytrap,接收信号为SIGINT
trap 'mytrap' INT #执行动作为函数mytrap,接收信号INT
mytrap() { #定义函数mytrap
echo "Now,you are doing the QUIT" #输出字符串到h.txt中
tail -5 /var/log/messages >> /root/h.txt #追加message后5 行到h.txt
exit 1 #退出
}
while true #while循环输出数字1111
do
/usr/bin/echo "111111"
done
[root@localhost ~]# ./test.sh
111111
^C111111
Now,you are doing the QUIT
【】# cat h.txt
Oct 22 18:00:01 localhost systemd: Started Session 27 of user root.
Oct 22 18:01:01 localhost systemd: Started Session 28 of user root.