bash脚本之条件判断
- 条件测试
- 数值比较
- 字符串比较
- 文件测试
- 组合测试条件
- 向脚本里传递参数
- if判断
- case语句
- for循环
- while循环
- until循环
- continue
- break
- 创建死循环
- while的特殊用法
- for的特殊用法
- select
条件测试
条件测试可以使用以下方法:
- 1、执行命令,并利用命令状态返回值来判断
- 0 :成功
- 1-255:失败
- 2、测试表达式
- test EXPRESSION
- [ EXPRESSION ]
- [[ EXPRESSION ]]
数值比较
表达式 | 解释 |
---|---|
-eq | 是否等于 |
-nq | 是否不等于 |
-gt | 左侧是否大于右侧 |
-ge | 左侧是否大于等于右侧 |
-lt | 是否小于 |
-le | 是否小于等于 |
字符串比较
表达式 | 解释 |
---|---|
== | 是否等于 |
> | 是否大于 |
< | 是否小于 |
!= | 是否不等于 |
=~ | 左侧的字符是否能够被右侧模式所匹配 |
-z “STRING” | 判定指定的字符串是否为空,空则为真,不空为假 |
-n “STRING” | 判定指定的字符串是否为不空,空则为假,不空为真 |
注意:字符串进行比较时,最好使用双括号,并添加“”号
文件测试
存在性测试
- -a FILE
- -e FILE
- 文件的存在性测试,存在为真,不存在为假,一般使用-e选项
存在性及类型测试
表达式 | 解释 |
---|---|
-b file | 是否存在并且为块设备文件 |
-c file | 是否存在并且为字符设备文件 |
-d file | 是否存在并且为目录文件 |
-f file | 是否存在并且为普通文件 |
-h OR -l file | 是否存在并且为符号链接文件 |
-p file | 是否存在并且为命名管道文件 |
-S file | 是否存在并且为套接字文件 |
** 文件权限测试**
表达式 | 解释 |
---|---|
-r file | 是否存在并且对当前用户可读 |
-w file | 是否存在并且对当前用户可写 |
-x file | 是否存在并且对当前用户可执行 |
特殊权限测试
表达式 | 解释 |
---|---|
-g file | 是否存在并且拥有sgid权限 |
-u file | 是否存在并且拥有suid权限 |
-k file | 是否存在并且拥有sticky权限 |
文件是否有内容
- -s FILE:是否有内容
文件时间戳测试
- -N FILE:文件自从上一次读取操作后是否被修改过
从属关系测试
- -O FILE:当前用户是否为文件的属主
- -G FILE:当前用户是否属于文件的属组
组合测试条件
逻辑运算
COMMAND1&& COMMAND2
COMMAND1 || COMMAND2:为真,执行comm1 否则执行comm2
!COMMAND1
第二种方式:
EXPRESSION1 -a EXPRESSION 2
EXPRESSION1 -o EXPRESSION 2
!EXPRESSION
向脚本里传递参数
位置参数变量:
- $1,$2, 3.... 3.... 3....{10}…
轮替:shift [n] :消除n个参数
特殊变量:
- $0:脚本文件路径本身
- $#:脚本参数的个数
- $*:所有参数
- $@:所有参数
if判断
过程式编程语言的代码执行顺序:
- 顺序执行:逐条运行
- 选择执行:
- 代码存在一个分支,条件满足时才会执行
- 代码存在两个或两个以上分支,只会执行其中一个分支
- 循环执行 :代码片段执行0,1或多个来回
显然if属于里面的选择执行,其使用方法是:
单分支:
if 测试条件; then
执行语句
fi
双分支:
if 测试条件; then
执行语句
else
为假是执行语句
fi
多分支的if语句:
if 测试条件1;then
条件1为真分支
elif 测试条件2;then
条件2为真分支
elif 测试条件3;then
条件3位真分支
......
elif 测试条件n;then
条件n为真分支
else
所有条件均不满足时分支
fi
注意:if语句即便有多个条件都为真,分支也只能执行最开始的一个。之后的执行条件都不会执行
示例:编写脚本/root/bin/,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息
#!/bin/bash
username=$1
if [[ "$1" =~ ^[0-9]+ ]];then
echo "number is invalid" && exit 1
fi
if [ -z "$1" ];then
echo "please input a username" && exit 2
fi
if [ -z "`id -u $1`" ];then
useradd $1
echo `id $1`
else
echo "user exist"
fi
编写脚本/root/bin/,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息
#!/bin/bash
read -p "please input the yse or no:" word
if [[ "$word" =~ [yYeESs] ]];then
echo "yes"
elif [[ "$word" =~ [nNOo] ]];then
echo "no"
else
echo "input error"
exit 1
fi
case语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b
示例:
写一个脚本
(1) 列出如下菜单给用户:
disk) show disks info;
mem) show memory info;
cpu) show cpu info;
*) quit;
(2) 提示用户给出自己的选择,而后显示对应其选择的相应系统信息;
#!/bin/bash
echo -e "\ndisk) show disks info \nmem) show memory info \ncpu) show cpu info\n*) quit"
read -p "please input your choice:" choose
case $choose in
disk)
df -h
;;
mem)
cat /proc/meminfo
;;
cpu)
lscpu
;;
*)
exit 1
;;
esac
for循环
循环意味着一个代码片段要重复执行多次,重复执行也分为已知的循环次数和未知的循环次数。已知的话使用for循环,未知使用while循环。
for循环
for 变量名 in 列表;do
循环体
done
执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
列表生成方式:
- 直接给出列表
- 整数列表:
- a){start…end}
- b)$(seq [start [step] end])
- 返回列表的命令:$(COMMAND)
- 使用glob,如:*.sh
- 变量引用:$@,$*…
示例:编写脚本,提示输入正整数n的值,计算1+2+…+n的总和
1 #!/bin/bash
2 declare -i i=0;
3
4 read -p "please input a num:" num
5
6 for j in $(seq 1 $num);do
7 i=$[$i+$j]
8 done
9 echo $i
示例:打印九九乘法表
1 #!/bin/bash
2 for i in {1..9};do
3 for j in {1..9};do
4 if [ $i -ge $j ];then
5 echo -n "$j*$i=$[$j*$i] "
6 fi
7 done
8 echo
9 done
示例:打印等腰三角形
1 #!/bin/bash
2 for ((i=1;i<=5;i++));do
3 for ((j=$[5-$i];j>0;j--));do
4 echo -n " "
5 done
6 for ((k=1;k<=$[$i*2-1];k++));do
7 echo -n "*"
8 done
9 echo
10 done
while循环
while CONDITION; do
循环体
done
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION为true
退出条件:CONDITION为false
示例:打印九九乘法表
1 #!/bin/bash
2 declare -i i=1
3 while [ $i -le 9 ];do
4 declare -i j=1
5 while [ $i -ge $j ];do
6 echo -n "$j*$i=$[$i*$j] "
7 let j++
8 done
9 let i++
10 echo
11 done
until循环
until CONDITION; do
循环体
循环控制变量修正表达式
done
进入条件:CONDITION测试为“假”
退出条件:CONDITION测试为“真”
示例:打印逆序的九九乘法表
1 #!/bin/bash
2 declare -i i=9
3 until [ $i -lt 1 ];do
4 declare -i j=1
5 until [ $j -gt $i ];do
6 echo -n "$i*$j=$[$i*$j] "
7 let j++
8 done
9 let i--
10 echo
11 done
~
continue
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done
示例:求100以内的所有偶数之和
1 #!/bin/bash
2 declare -i j=0
3 for i in {1..100};do
4 if ! [ $[$i % 2] -eq 0 ];then
5 continue
6 fi
7 j=$[$i+$j]
8 done
9 echo $j
~
break
用于循环体中
break [N]:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done
创建死循环
while true; do
循环体
done
退出方式:
某个测试条件满足时,让循环体执行break命令
示例:求100以内所奇数之和
1 #!/bin/bash
2 declare -i j=0
3 while true;do
4 for ((i=1;i<=10;i++));do
5 if [ $[$i%2] -eq 0 ];then
6 continue
7 fi
8 j=$[$j+$i]
9 done
10 break
11 done
12 echo $j
while的特殊用法
while循环的特殊用法(遍历文件的行):
while read VARIBLE; do
循环体
done < /PATH/FROM/SOMEFILE
依次读取/path/from/somefile文件中的每一行,且将其赋值给VARIABLE变量
示例:找出ID号为偶数的用户,显示其用户名、ID及默认shell
1 #!/bin/bash
2 while read line;do
3 i=`echo $line | cut -d: -f3 `
4 if [ $[$i%2] -eq 0 ];then
5 getent passwd $i
6 fi
7 done < /etc/passwd
for的特殊用法
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
条件判断表达式:可以使用> < = >= <=来标识
上边的打印等腰三角形就是使用此种方式
select
select variable in list
do
循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示 PS3 提示符, 等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量 REPLY 中
1 #!/bin/bash
2 select color in green red yellow quit;do
3 case $color in
4 green)
5 echo -e "your select the \e[32;1m $color \e[0m"
6 ;;
7 red)
8 echo -e "your select the \e[31;1m $color \e[0m"
9 ;;
10 yellow)
11 echo -e "your select the \e[33;1m $color \e[0m"
12 ;;
13 quit)
14 exit
15 ;;
16 esac
17 break
18 done