shell编程中的条件判断,循环,函数使用(shell 05)
shell编程中的条件判断
: 表示为真
条件
if-then
case
if-then
单条件
if command
then
commands
fi
当command返回码为0时 条件成立
在if,elif中要注意
中括号 [] 里面左右两边必须要有空格
== 两边也必须有空格 否者也不对
if.sh #! /bin/bash if : then echo true fi [root@centos1 sh]# sh -x if.sh + '[' 1 == 1 ']' + echo true true
[root@centos1 sh]# cat if.sh #! /bin/bash arg=$1 a=${arg:=2} if [ $a -gt 2 ] then echo "a>2" elif [ $a == 2 ] then echo "a=2" else echo "a<2" fi [root@centos1 sh]# bash -n if.sh [root@centos1 sh]# ./if.sh a=2 [root@centos1 sh]# ./if.sh 1 a<2 [root@centos1 sh]# ./if.sh 3 a>2
以上if.sh也可以写成
(()) 运算必须是整数
[root@centos1 sh]# cat if.sh #! /bin/bash arg=$1 #如果没传值,给一个默认值 a=${arg:=2} #如果出现小数 要过滤,否者出现错误,取.前面的整数 a=${a%%.*} if (($a>2)) then echo "a>2" elif (($a==2)) then echo "a=2" else echo "a<2" fi [root@centos1 sh]# sh -x if.sh 2.5 + arg=2.5 + a=2.5 + a=2 + (( 2>2 )) + (( 2==2 )) + echo a=2 a=2 [root@centos1 sh]# sh -x if.sh + arg= + a=2 + a=2 + (( 2>2 )) + (( 2==2 )) + echo a=2 a=2 [root@centos1 sh]# sh -x if.sh 3.1 + arg=3.1 + a=3.1 + a=3 + (( 3>2 )) + echo 'a>2' a>2
输入数字,判断奇数偶数
首先判断是否是数字
[root@centos1 sh]# cat odd.sh #! /bin/bash read -p "请输入一个数字:" n count=`echo $n|grep -c [^0-9]` if (($count>0)) then echo "not a num " exit fi n1=$[$n%2] if (($n1==0)) then echo "$n 是偶数" elif [ $n1 -eq 1 ] then echo "$n 是奇数" fi [root@centos1 sh]# sh -x odd.sh + read -p $'\350\257\267\350\276\223\345\205\245\344\270\200\344\270\252\346\225\260\345\255\227:' n 请输入一个数字:123 ++ echo 123 ++ grep -c '[^0-9]' + count=0 + (( 0>0 )) + n1=1 + (( 1==0 )) + '[' 1 -eq 1 ']' + echo '123 是奇数' 123 是奇数
if.sh
#! /bin/bash if date then echo "command exec" fi if date123 then echo "command exec1" fi echo "out if" [root@localhost110 sh]# ./if.sh 2016年 10月 29日 星期六 10:39:18 EDT command exec ./if.sh: line 8: date123: command not found out if
全覆盖
if command
then
commands
else
commands
fi
if 后直接跟命令
$? 可以获取上一个命令的退出状态,就是上一个命令执行后的返回结果
退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1
不过,也有一些命令返回其他值,表示不同类型的错误
[root@bogon sh]# if ls -al /dd; then echo 123;else echo 456; fi ls: 无法访问/dd: 没有那个文件或目录 456 [root@bogon sh]# if ls -al /dd; then echo 123;else echo 456; fi 2>/dev/null 456 [root@bogon sh]# echo abc|grep -qc [^0-9] [root@bogon sh]# echo $? 0 [root@bogon sh]# echo 123|grep -qc [^0-9] [root@bogon sh]# echo $? 1 [root@bogon sh]# cat odd.sh #! /bin/bash read -p "请输入一个数字:" n if echo $n|grep [^0-9] -cq then echo "not a num " exit fi n1=$[$n%2] if (($n1==0)) then echo "$n 是偶数" elif [ $n1 -eq 1 ] then echo "$n 是奇数" fi [root@bogon sh]# sh odd.sh 请输入一个数字:12 12 是偶数 [root@bogon sh]# sh odd.sh 请输入一个数字:ab123 not a num
在 -gt ,-lt等操作运算符时,参与的必须是整数,否者会报错
-z $n 可判断$n是否为空返回真,非空返回假
[root@centos1 ~]# n=1 [root@centos1 ~]# echo $n 1 [root@centos1 ~]# if [ -z $n ] ;then echo 11;else echo 22;fi 22 [root@centos1 ~]# unset n [root@centos1 ~]# if [ -z $n ] ;then echo 11;else echo 22;fi 11 [root@centos1 ~]# if [ ! -z $n ] ;then echo 11;else echo 22;fi 22
注意 !和-z之间必须有空格
if.sh
#! /bin/bash if date1 then echo "command" echo "ok" else echo "commond1" echo "fail" fi [root@localhost110 sh]# ./if.sh ./if.sh: line 2: date1: command not found commond1 fail
条件嵌套
if command1
then
commands
if command2
then
commands
fi
commands
fi
多条件
if command1
then
commands
elif command2
then
commands
else
commands
fi
test命令:
第一种形式
if test condition
then
commands
fi
第二种形式
中括号 []
if [ condition ]
then
commands
fi
复合条件判断
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
condition左右2边一定需要有空格 否者不能正确的执行
三类条件
数值比较
字符串比较
文件比较
if.sh
echo plese input a num read num if [ $num -gt 10 ] then echo "the num>10" fi if [ $num -lt 10 ] && [ $num -gt 5 ] then echo "the 5<num<10" fi
[root@localhost110 sh]# ./if.sh plese input a num 11 the num>10
常用判断条件
数值比较
= n1 -eq n2
>= n1 -ge n2
> n1 -gt n2
< n1 -lt n2
<= n1 -le n2
!= n1 -ne n2
compare.sh及其调用结果
#! /bin/bash if [ $1 -eq $2 ] then echo "$1=$2" elif [ $1 -gt $2 ] then echo "$1>$2" else echo "$1<$2" fi 运行结果 [root@localhost110 sh]# ./compare.sh 1 1 1=1 [root@localhost110 sh]# ./compare.sh 1 2 1<2 [root@localhost110 sh]# ./compare.sh 2 1 2>1 [root@localhost110 sh]# ./compare.sh 1 a ./compare.sh: line 3: [: a: integer expression expected ./compare.sh: line 6: [: a: integer expression expected 1<a
字符串比较
str1 = str2 相同
str1 != str2 不同
str1 > str2 str1比str2大 (ascll码逐位比较)
str1 < str2 str1比str2小
-n str1 字符串长度是否非0
-z str1 字符串长度是否为0
文件比较
-d file 检查file是否存在并是一个目录
-e file 检查file是否存在
-f file 检查file是否存在并是一个文件
-s file 检查file是否存在并非空
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
-r file 检查file是否存在并可读
-w file 是否存在并可写
-x file 是否存在并可执行
-O file 是否存在并属当前用户所有
-G file 是否存在并且默认组与当前用户相同
高级判断
(( expression )) 高级数学表达式
[[ expression ]] 高级字符串比较
if (($1<$2)) then echo $1,$2; echo $1\<$2; elif (($1==$2)) then echo $1==$2 else echo $1\>$2 fi
case
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands3;;
*) default commands ;;
esac
#! /bin/bash case $1 in 1|11|111) echo 1_$1;; 2) echo 2_$1; echo 2_$1;; 3) echo 3_$1;; esac
[root@centos1 sh]# cat t.sh #! /bin/bash read -p "请输入一个整数:" n if [ -z $n ] then echo "请输入参数";exit 1 fi n1=`echo $n|sed 's/[0-9]//g'` if [ ! -z $n1 ] then echo "请输入一个整数" exit fi if [ $n -lt 60 ] then tag=1 elif [ $n -ge 60 ]&&[ $n -lt 70 ] then tag=2 elif [ $n -ge 70 ]&&[ $n -lt 80 ] then tag=3 elif [ $n -ge 80 ]&&[ $n -lt 90 ] then tag=4 elif [ $n -ge 90 ]&&[ $n -le 100 ] then tag=5 else tag=0 fi case $tag in 1) echo "不及格";; 2) echo "差";; 3) echo "良好";; 4|5) echo "优秀";; *) echo "range is 1-100";; esac
注意* 不可放在第一位,因为从上到下 找到即停止
for 循环
写法:
1. for i in `seq 1 5`;do echo $i;done; 2. for((i=0;i<5;i++)) do echo $i;done; 3. for i in `ls`;do echo $i;done; 4. for i in a b c dd e;do echo $i;done; 5. for i in `cat file`;do echo $i;done; //遍历file里的每一行(根据分割符号 IFS) 6. for i in '*.txt';do echo $i;done; //遍历当前目录下 .txt结尾的文件 7. list="a b c d";for i in $list;do echo $i;done;
seq
用法:seq [选项]... 尾数
或:seq [选项]... 首数 尾数
或:seq [选项]... 首数 增量 尾数
以指定增量从首数开始打印数字到尾数。
-f, --format=格式 使用printf 样式的浮点格式
-s, --separator=字符串 使用指定字符串分隔数字(默认使用:\n)
-w, --equal-width 在列前添加0 使得宽度相同
--help 显示此帮助信息并退出
--version 显示版本信息并退出
如果省略了首数或者增量,则默认其值为1,即使这样尾数仍小于首数。
首数、增量和尾数均以浮点数形式解释。当首数小于尾数时增量一般为正值,
相反在首数大于尾数时增量一般为负数。
指定的格式必须适用于显示"double"类型的参数;当首数、增量和尾数均为指定
精确度的定点十进制数时默认为"%.精确度f",否则默认为"%g"。
求 1,10的和
[root@bogon sh]# cat 100.sh #!/bin/bash sum=0; for i in `seq 1 10` do sum=$[$sum+$i] done echo $sum [root@bogon sh]# cat cal.sh #!/bin/bash a=1 b=2.51 c=`echo "scale=3;$a+$b"|bc` echo $c
取出t.txt的每一行
[root@bogon sh]# cat t.txt 1 2 3 4 5 6 7 8 9
第一种方式不符合(受默认分割符号影响)
[root@bogon sh]# for line in `cat t.txt` ;do echo $line;done; 1 2 3 4 5 6 7 8 9
第一种方式修改完善,修改默认IFS
IFS=$'\n'
或者
IFS='
'
[root@bogon sh]# cat t1.sh #! /bin/bash #输出老的默认分割符 echo "$IFS"|od -b #修改默认分割符为换行 IFS=" " echo "$IFS"|od -b for line in `cat t.txt` do echo $line done
第二种方式(取出行号,然后sed取行)
t.sh
#! /bin/bash line_num=`wc -l t.txt|cut -d ' ' -f 1` for i in `seq 1 $line_num` do echo `sed -n "${i}p" t.txt` done while
while
[root@centos1 sh]# cat while.sh #! /bin/bash while : do read -p "请输入参数: " n; if [ -z $n ] then echo "请输入些什么:" continue fi m=`echo $n|sed 's/[0-9]//g'` if [ ! -z $m ] then echo "请输入一个正整数:"; continue; fi echo $n; break; done
函数
必须先声明 才能调用,顺序加载
shell中变量是全局的,函数里的变量默认也是全局的 作用于从函数被调用时执行变量定义的地方开始,到脚本结束
函数内可以读取到函数外已经定义的变量
也可以显式定义为只在函数里生效 使用local
如果同名,Shell函数定义的local变量会屏蔽脚本定义的global变量
$n 表示第n各参数
[root@centos1 sh]# cat fun.sh #! /bin/bash fun(){ echo "函数内读取a:"$a; a=100; b=2; local c=5 echo "函数内读取c:"$c } a=1 fun echo "函数外读取a:"$a echo "函数外读取b:"$b echo "函数外读取c:"$c [root@centos1 sh]# sh fun.sh 函数内读取a:1 函数内读取c:5 函数外读取a:100 函数外读取b:2 函数外读取c: [root@centos1 sh]# cat fun1.sh #! /bin/bash fun(){ echo $a; local a=10; echo $a } a=1 fun echo $a [root@centos1 sh]# sh fun1.sh 1 10 1 [root@centos1 sh]# cat f.sh #! /bin/bash fun(){ echo $1-$2-$3-$4 } fun a b c d fun a b c fun a b c d e [root@centos1 sh]# sh f.sh a-b-c-d a-b-c- a-b-c-d
查看ip
ifconfig|grep 'eth0' -A1|tail -1|awk '{print $2}'|cut -d ':' -f2 或者 ifconfig|grep 'eth0' -A1|tail -1|awk '{print $2}'|awk -F ':' '{print $2}'
until
#!/bin/bash i=0 until (($i>10)) do echo $i i=$[$i+1] i=`expr $i + 1` done;