bash脚本-循环02
bash脚本编程:循环
执行流程:
1.顺序执行
2.选择执行:if
3.循环执行:for,while,until
1.循环执行的条件
进入条件:
for:列表元素非空
while:条件测试结果为“真”
until:条件测试结果为“假”
推出条件:
for:列表元素遍历完成
while:条件测试结果为“假”
until:条件测试结果为“真”
2.循环控制语句:continue,break,sleep
2.1continue
提前结束本轮循环,而直接进入下一轮循环判断
while CONDITION1;do
cmd1
...
if condition2;then
continue
fi
cmd2
...
done
例:求100以内所有偶数之和
#/bin/bash
#
declare -i sum=0
declare -i i=0
while [ $i -le 100 ];do
let i++
if [ $[$i%2] -eq 1 ];then
continue
fi
let sum+=$i
done
echo "sum is $sum"
2.2 break
提前跳出循环
while CONDITION1;do
CMD1
if CONDITION2;then
break
fi
done
创建死循环
while true;do
循环体
done
退出方式:某个测试条件满足之后,让循环体执行break命令
例:求100以内所有奇数之和
#!/bin/bash
declare -i sum=0
declare -i i=1
while true;do
let sum+=$i
let i+=2
if [ $i -gt 100 ];then
break
fi
done
echo "sum is $sum"
2.3 sleep命令
sleep-delay for a specified amount of time
sleep NUMBER
下面通过一个例子说明sleep的用法
例:每隔3秒钟到系统上获取已经登录用户的用户的信息;其中,如果zhangpf用户登录了系统,则记录于日志中,并退出;
方法1
#!/bin/bash
name=zhangpf
- until (who | grep "^$name\>" &> /dev/null);do
echo $?
sleep 3
done
echo "$(date +"%F-%T") $name logged on" >> /tmp/sleep.log
方法2
#!/bin/bash
name=zhangpf
while true;do
if who | grep "^$name\>" &> /dev/null;then
break
fi
sleep 3
done
echo "$(date +"%F-%T") $name logged on" >> /tmp/login.log
3.循环体的特殊用法
3.1 while循环的特殊用法(遍历文件的行)
while read VARIABLE;do
循环体;
done < /path/to/somefile
#依次读取/path/to/somefile文件中的每一行,且将基赋值给VARIABLE变量;
下面通过示例说明:
示例:找出UID为偶数为的用户,显示其用户名、ID及默认shell
#!/bin/bash
while read line;do
id=$(echo $line | cut -d: -f3)
name=$(echo $line | cut -d: -f1)
shell=$(echo $line | cut -d: -f7)
if [ $[$id%2] -eq 1 ];then
echo "$name,$id,$shell."
fi
done < /etc/passwd
3.2 for的特殊用法:
for ((控制变量初始化;条件判断表达式;控制变量的修正语句));do
循环体
done
控制变量初始化:仅在循环代码开始运行时执行一次
控制变量的修正语句:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
示例:
#!/bin/bash
declare -i sum=0
for ((i=0;i<=100;i++));do
let sum+=$i
done
echo "sum=$sum"
打印九九乘法表:
#!/bin/bash
for ((i=1;i<=9;i++));do
for ((j=1;j<=i;j++));do
echo -e -n "${i}X${j}=$[${i}*${j}]\t"
done
echo
done
4.bash语句之case语句
case语句的语法格式:
case $VARIABLE in
PAT1)
分支1
;;
PAT2)
分支2
;;
。。。。
*)
分支n
;;
esac
case支持glob风格的通配符:
*:任意长度的任意字符
?:任意单个字符
[]:范围内任意单个字符
a|b:a或b
示例:写一个服务框架脚本$lockfile, 值/var/lock/subsys/SCRIPT_NAME
(1) 此脚本可接受start, stop, restart, status四个参数之一;
(2) 如果参数非此四者,则提示使用帮助后退出;
(3) start,则创建lockfile,并显示启动;stop,则删除lockfile,并显示停止;restart,则先删除此文件再创建此文件,而后显示重启完成;status,如果lockfile存在,则显示running,否则,则显示为stopped.
#!/bin/bash
#version 0.0.1
#author:zhangpf
#date:2016.07
#description:this just a test.
#
prog=$(basename $0)
lockfile=/var/lock/subsys/$prog
case $1 in
start)
if [ -f $lockfile ];then
echo "$prog is running yet."
else
touch $lockfile
[ $? -eq 0 ] && echo "start $prog finished."
fi
;;
stop)
if [ -f $lockfile ];then
rm -f $lockfile
[ $? -eq 0 ] && echo "stop $prog is finished."
else
echo "$prog is not running."
fi
;;
restart)
if [ -f $lockfile ];then
rm -f $lockfile
touch $lockfile
echo "restart $prog finished."
else
touch -f $lockfile
echo "start $prog finished."
fi
;;
status)
if [ -f $lockfile ];then
echo "$prog is running."
else
echo "$prog is stopped."
fi
;;
*)
echo "Usage:$prog {start|stop|restart|status}"
exit 1
esac
上面的就是一个简单的使用示例。
透过这个示例,我们可以看到,shell自动化脚本,自动化编译安装各种程序,重要的是要考虑到可能会发生的各种问题,对每一个可能遇到的问题进行分析,解决。其他的就是对于代码的堆砌,考验的就是对于基础的掌握了。