shell编程-流程控制-if-case-for
流程控制
1. if语句
我们直接来了解多分支吧,但分支和双分支太简单了,它包含在多分支里面
格式:
if [判断条件1]
then
条件1成立时,执行的程序
elif [判断条件2]
then
条件2成立时,执行的语句
...
else
当所有条件都不成立,执行的语句
fi
来个完整的四则运算脚本吧
#!/bin/bash
read -p "请输入数字1:" num1
read -p "请输入数字2:" num2
read -p "请输入你需要的运算符【+ - * / %】:" oper
if [ -n "$num1" -a -n "$num2" -a -n "$oper" ]
then
tt1=$(echo $num1 | sed s/[0-9]//g)
tt2=$(echo $num2 | sed s/[0-9]//g)
if [ -n "$tt1" -o -n "$tt2" ]
then
echo "ERR-13:请输入正确的数字!!!"
exit 13
else
if [ "$oper" == '+' ]
then
value=$(( $num1 + $num2 ))
elif [ "$oper" == "-" ]
then
value=$(( $num1 - $num2 ))
elif [ "$oper" == "/" ]
then
value=$(( $num1/$num2 ))
elif [ "$oper" == "*" ]
then
value=$(( $num1 * $num2 ))
elif [ "$oper" == "%" ]
then
value=$(( $num1 % $num2 ))
else
echo "ERR-12:请输入正确的运算符!!!"
exit 12
fi
echo "这是你的运算结果:$num1 $oper $num2 = $value"
fi
else
echo "ERR-14:请输入内容!!!"
exit 14
fi
妈的,有个三层的if嵌套,可能不好理解,但愿后面能看懂吧~
2. case语句
这种东西只能判断某个变量里的值是些什么东西~这个比如上面的四则运算就可以用case来写。
格式:
case $变量名 in
"值1")
变量=值1,执行的程序
;;
"值2")
变量=值2,则执行的程序
;;
*)
以上的值都不对,则执行的程序
;;
esac
四则运算:
#!/bin/bash
read -p "请输入数字1:" num1
read -p "请输入数字2:" num2
read -p "请输入你需要的运算符【+ - * / %】:" oper
if [ -n "$num1" -a -n "$num2" -a -n "$oper" ]
then
tt1=$(echo $num1 | sed s/[0-9]//g)
tt2=$(echo $num2 | sed s/[0-9]//g)
if [ -n "$tt1" -o -n "$tt2" ]
then
echo "ERR-13:请输入正确的数字!!!"
exit 13
else
case $oper in
"+")
value=$(( $num1 + $num2 ))
;;
"-")
value=$(( $num1 - $num2 ))
;;
"/")
value=$(( $num1/$num2 ))
;;
"*")
value=$(( $num1 * $num2 ))
;;
"%")
value=$(( $num1 % $num2 ))
;;
*)
echo "ERR-12:请输入正确的运算符!!!"
exit 12
;;
esac
echo "这是你的运算结果:$num1 $oper $num2 = $value"
fi
else
echo "ERR-14:请输入内容!!!"
exit 14
fi
3. for循环
3.1 for格式
格式1:
循环次数取决于in后面的变量数,每次循环把值赋给变量
#!/bin/bash
for tt in a b c d e
do
echo $tt
done
格式2:
注意for的格式,必须是双括号,第一个为变量初始值,二维变量控制条件,三为变量变化规律
#!/bin/bash
sum=0
for (( i=0; i<=100; i=i+1))
do
sum=$(( $sum + $i ))
done
echo "1+2+3...+100=$sum"
3.2 for应用1–批量解压缩
3.2.1 方案1
我在/opt/test下面准备了一些压缩包
这个脚本的缺陷:
- 相当于规定了压缩格式
- 目录下面不能有其他文件
- 解压缩命令单一
解决方案:
- 文件名获取应该先把其他文件排除
- 根据不同的类型,写不同的解压命令
#!/bin/bash
lines=$( ls -l '/opt/test'|grep -v total|awk '{print $9}'|wc -l )
echo $lines
for (( i=1;i<=$lines;i=i+1 ))
do
filename=$( ls -l '/opt/test'|grep -v total|awk '{print $9}'|awk 'NR=='$i'{print $1}' )
echo $filename
tar -zxvf /opt/test/$filename
done
里面有很多awk的应用,挺好的,回忆一下:
NR:表示当前处理第几行
3.2.2 方案2
for的第一种格式可以接受命令的结果,这是我之前忽略的,这样子其实就很好写了
#!/bin/bash
for i in $( ls -l /opt/test/*.tar.gz|awk '{print $9}' )
do
tar -zxvf $i
done
明显看到,这种简单很多。
3.3 for应用-合法IP地址判断
我们在ips.txt文件里放了一些疑似IP地址:
现在,我们要把合法的找出来:
#!/bin/bash
lines=$( wc -l /opt/mysh/ips.txt | awk '{print $1}')
echo "" >/opt/mysh/ip_real.txt
for (( i=1;i<=$lines;i=i+1 ))
do
#先排除一些不是四个数字相连的IP
ip_tmp=$(awk 'NR=='$i'{print $1}' /opt/mysh/ips.txt | grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$")
if [ -z $ip_tmp ];then
echo "$ip_tmp out"
continue
else
ip_1=$( echo $ip_tmp|cut -d "." -f1 )
ip_2=$( echo $ip_tmp|cut -d "." -f2 )
ip_3=$( echo $ip_tmp|cut -d "." -f3 )
ip_4=$( echo $ip_tmp|cut -d "." -f4 )
if [ "$ip_1" -lt 0 -o "$ip_1" -gt 255 ];then
continue
fi
if [ "$ip_2" -lt 0 -o "$ip_2" -gt 255 ];then
continue
fi
if [ "$ip_3" -lt 0 -o "$ip_3" -gt 255 ];then
continue
fi
if [ "$ip_4" -lt 0 -o "$ip_4" -gt 255 ];then
continue
fi
echo $ip_tmp >>/opt/mysh/ip_real.txt
fi
done
# 删除第一个空白行
sed -i /^$/d ip_real.txt
运行结果:
其实,这个脚本用另一种循环方式写更简单。大致思路,我们初步筛选掉不合规则的IP地址之后,把剩余的IP地址放入到一个文件中,然后 for i in …