bash脚本条件判断语句详细使用
条件判断的使用方法及其相关示例;
本文对bash中test语句,if判断语句(单分支,多分支)case语句详细说明,如下
条件测试:test
作用:Shell中的test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
test使用语法
test EXPRESSION
也可以使用 :[ EXPRESSION ];[[ EXPRESSION ]]
整数测试:
隐含着做数值大小比较,所以不要给变量引用加引用;
$A -gt $B:是否大于;是则为“真”,否则为“假”;
$A -ge $B: 是否大于等于;
$A -lt $B:是否小于;
$A -le $B: 是否小于等于;
$A -eq $B: 是否等于;
$A -ne $B:是否不等于;
示例:整数判断,判断$A,$B的值,是则为“真”(0),否则为“假”(非零);
[root@os01 ~]# cat test.sh #!/bin/bash declare -i A=5 declare -i B=7 echo "$A=5" echo "$B=7" echo "以下判断$A,$B的值,是则为“真”(0),否则为“假”(非零);" echo "$A -gt $B:是否大于;" test $A -gt $B; echo $? echo "$A -ge $B: 是否大于等于;" test $A -ge $B;echo $? echo "$A -lt $B:是否小于;" test $A -lt $B;echo $? echo "$A -le $B: 是否小于等于;" [ $A -le $B ] ;echo $? echo "$A -eq $B: 是否等于;" [ $A -eq $B ];echo $? echo "$A -ne $B:是否不等于;" [ $A -ne $B ];echo $? [root@os01 ~]# ./test.sh 5=5 7=7 以下判断5,7的值,是则为“真”(0),否则为“假”(非零); 5 -gt 7:是否大于; 1 5 -ge 7: 是否大于等于; 1 5 -lt 7:是否小于; 0 5 -le 7: 是否小于等于; 0 5 -eq 7: 是否等于; 1 5 -ne 7:是否不等于; 0
字符串测试:
ASCII数值越大,字符比较时其值越大;
"$A" > "$B":是否大于;
"$A" < "$B":是否小于;
"$A" == "$B":是否等于;
"$A" != "$B":是否不等于;
-z "$A":是否为空;空则为“真”,否则为“假”
-n "$A":是否不空;不空则“真”,空则为“假”
注意:应该使用[[ EXPRESSION ]]
示例:字符串测试,测试$A与$B
[root@os01 ~]# cat test01.sh #!/bin/bash A=hello B=world echo "A is hello" echo "B is world" echo "测试字符串$A,$B,是则为“真”(0),否则为“假”(非零);" echo ""$A" > "$B":是否大于;" [[ "$A" > "$B" ]];echo $? echo ""$A" < "$B":是否小于;" [[ "$A" < "$B" ]];echo $? echo ""$A" == "$B":是否等于;" [[ "$A" == "$B" ]];echo $? echo ""$A" != "$B":是否不等于;" [[ "$A" != "$B" ]];echo $? echo "-z "$A":是否为空;空则为“真”,否则为“假”" [[ -z "$A" ]];echo $? echo "-n "$A":是否不空;不空则“真”,空则为“假”" [[ -n "$A" ]];echo $? [root@os01 ~]# ./test01.sh A is hello B is world 测试字符串hello,world,是则为“真”(0),否则为“假”(非零); hello > world:是否大于; 1 hello < world:是否小于; 0 hello == world:是否等于; 1 hello != world:是否不等于; 0 -z hello:是否为空;空则为“真”,否则为“假” 1 -n hello:是否不空;不空则“真”,空则为“假” 0
文件测试:
测试文件的存在性以及属性;
-e $file: 是否存在;存在则为“真”,否则为“假”;
-a $file: 同上;
-f $file:文件是否存在且为普通文件;
-d $file:文件是否存在且为目录;
-h $file:是否存在且为符号链接文件;
-L $file: 同上
-b $file:是否存在且为块设备文件;
-c $file:是否存在且为字符设备文件;
-S $file:是否存在且为套接字文件;
-p $file: 是否存在且为管道文件;
-r $file: 当前用户对文件是否拥有读权限;
-w $file:当前用户对文件是否拥有写权限;
-x $file:当前用户对文件是否拥有执行权限;
-u $file:文件是否拥有SUID权限;
-g $file:文件是否拥有SGID权限;
-k $file:文件是否拥有sticky权限;
-O $file: 当前用户是否为指定文件的属主;
-G $file: 当前用户是否为指定文件的属组;
双目操作符:
$file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2
的;
$file1 -ot $file2: file1是否旧于file2, file1的最近一次的修改时间戳是否早于file2
的;
$file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;
示例:常用选项:-e -f -d;-w -x;-u;-nt -ot;
#-e 是否存在,可以是目录,文件等 [root@os01 ~]# test -e /dir #是否存在(目录) [root@os01 ~]# echo $? 0 [root@os01 ~]# touch /dir/file1 [root@os01 ~]# test -e /dir/file1 #是否存在(文件) [root@os01 ~]# echo $? 0 [root@os01 ~]# rm -f /dir/file1 [root@os01 ~]# test -e /dir/file1 [root@os01 ~]# echo $? 1 #删除后没有file1文件,返回结果为1 #-f,文件是否存在且为普通文件;针对文件 [root@os01 ~]# touch /dir/file1 [root@os01 ~]# test -f /dir/file1 [root@os01 ~]# echo $? 0 [root@os01 ~]# test -f /dir/ #测试dir为目录,虽然存在但是不是普通文件,返回结果为1 [root@os01 ~]# echo $? 1 #-d,文件是否存在且为目录;针对目录drwxr-xr-x 第一个d [root@os01 ~]# test -d /dir [root@os01 ~]# echo $? 0 [root@os01 ~]# test -d /dir/file1 #测试file1为文件,虽然存在但是不是目录,返回结果为1 [root@os01 ~]# echo $? 1 #-w,当前用户对文件是否拥有写权限;-x,当前用户对文件是否拥有执行权限; test -w /dir/file1 test -x /dir/file1 #-u,文件是否拥有SUID权限; [root@os01 ~]# test -u /dir/file1 [root@os01 ~]# echo $? 1 [root@os01 ~]# chmod u+s /dir/file1 [root@os01 ~]# test -u /dir/file1 [root@os01 ~]# echo $? 0 #-nt,file1是否新于file2,判断基于最近一次的修改时间戳 #-ot,file1是否旧于file2,判断基于最近一次的修改时间戳 [root@os01 ~]# touch file1 && date +%M%S 0133 [root@os01 ~]# touch file2 && date +%M%S 0139 [root@os01 ~]# test file1 -nt file2 #file1是否新于file2(否) [root@os01 ~]# echo $? 1 [root@os01 ~]# test file2 -nt file1 #file2是否新于file1(是) [root@os01 ~]# echo $? 0 [root@os01 ~]# echo "hello world">file1 #修改file1 [root@os01 ~]# cat file1 hello world [root@os01 ~]# test file1 -nt file2 #file1因为修改了,所以新于file2了 [root@os01 ~]# echo $? 0
特殊设备:
/dev/null: 空,bit buckets,吞下所有数据,并直接丢弃;
/dev/zero:吐出一堆0;
示例:
#/dev/null echo "hello world">/dev/null #标准输出重定向到/dev/null,无任何显示内容 [root@os01 ~]# error output bash: error: command not found... [root@os01 ~]# error input &>/dev/null #标准输出和标准错误输出都重定向到/dev/null,无任何显示内容 [root@os01 dir]# ls test.sh test1.sh ls: cannot access test1.sh: No such file or directory test.sh [root@os01 dir]# ls test.sh test1.sh >/dev/null 2>&1 #将错误输出2 绑定给 正确输出1,然后将正确输出发送给/dev/null设备,无任何内容显示 #/dev/zero 常用方法,制作一个100M大文件 [root@os01 dir]# dd if=/dev/zero of=bigfile bs=M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 1.75084 s, 59.9 MB/s [root@os01 dir]# du -h bigfile 100M bigfile
bash之条件判断(if语句)
if 语句通过关系运算符判断表达式的真假来决定执行哪个分支,有单分支和多分支if语句,下面详细介绍
单分支if语句
bash之条件判断:格式
if/then, case
if CONDITION; then
if-true-分支
fi
if CONDITION; then
if-true-分支
else
if-false-分支
fi
! CONDITION: 取反(条件取反)
示例:
#如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型; [root@os01 dir]# cat test.sh #!/bin/bash dirname="/dir/dir01" if [ -e $dirname ] then echo "$dirname exists." file $dirname else mkdir -p $dirname fi [root@os01 dir]# ./test.sh #目录不存在,所以创建了目录dir01 [root@os01 dir]# ls dir01 test.sh [root@os01 dir]# ./test.sh #目录以及存在,如下提示 /dir/dir01 exists. /dir/dir01: directory #!CONDITION:取反 [root@os01 dir]# if [ ! -z $test ];then echo "$test";else echo ‘$test is zero‘;fi hello
if语句使用脚本参数(位置参数变量),shift,read命令:
位置参数变量:$1, $2, ...
# ./script.sh /etc/fstab /etc/grub2.cfg
$0 $1 $2
特殊变量:
$?: 命令的状态结果;
$#: 传递给脚本或函数的参数的个数;
$*和$@: 引用传递给脚本或函数的参数列表;
shift [n]:轮替:shift命令会将之前的(左边的)参数删除,用右边的参数替换其位置。参 数表示替换几个(向左移几位)。shift不指定参数默认为1。
与用户交互:
read命令:
read [options] VAR...
-p "PROMPT":提示信息
-t timeout :等待时间
示例:参数位置与shift轮替
例子表示,因为shift将A2,A3依次往左移一位,所以echo$1,$1位置的A1分别被A2,A3逐次替换,最后的$*显示全部参数,因为之前的A1被A2替换,A2被A3所替换,所以最后的$*只剩下A3了.
[root@os01 dir]# cat shift.sh #!/bin/bash # echo $* echo $1 shift echo $1 shift echo $1 echo $* [root@os01 dir]# ./shift.sh A1 A2 A3 A1 A2 A3 A1 A2 A3 A3 #$*的值
示例:使用read读入参数变量username为用户名,添加一个用户,如果存在,提示用户存在,不存在则添加用户,等待时间为10秒,等待超时未输入参数变量username,添加指定用户myuser
[root@os01 dir]# cat adduser.sh #!/bin/bash read -p "Plz enter a username: " -t 10 username #提示输入参数变量,等待为10s if [ -z "$username" ] then username="myuser" fi if id $username &> /dev/null; then echo "$username exists." else useradd $username fi [root@os01 dir]# ./adduser.sh Plz enter a username: root root exists. [root@os01 dir]# ./adduser.sh Plz enter a username: user001 [root@os01 dir]# id user001 uid=1006(user001) gid=1006(user001) groups=1006(user001)
命令引用:
`COMMAND`, $(COMMAND)
引用命令的执行结果;
示例:
[root@os01 dir]# ls `which cat` /usr/bin/cat [root@os01 dir]# lines=$(wc -l /etc/fstab | cut -d‘ ‘ -f1) [root@os01 dir]# echo $lines 12 #统计指定文件行数 [root@os01 dir]# cat lines.sh #!/bin/bash # if [ -f $1 ] then lines=$(wc -l $1 | cut -d‘ ‘ -f1) echo "$1 has $lines lines." else echo "$1 not exists or not a file." fi [root@os01 dir]# ./lines.sh /etc/passwd /etc/passwd has 46 lines.
双分支if语句:
if CONDITION; then
if-true-分支
else
if-false-分支
fi
多分支if语句:
if CONDITION1; then
if-CONDITION1-true-分支
elif CONDTION2; then
if-CONDITIO2-true-分支
...
else
if-ALL-false-分支
fi
示例:多分支,通过脚本参数传递一个文件路径给脚本,判断其类型;
#!/bin/bash # if [ $# -lt 1 ]; then echo "Usage: $0 <path>" exit 1 fi if [ -f $1 ]; then echo "Rgular file." elif [ -d $1 ]; then echo "Directory." elif [ -h $1 ]; then echo "Symbolic link." elif [ -b $1 ]; then echo "Block special." elif [ -c $1 ]; then echo "Charactoer special." elif [ -S $1 ]; then echo "Socket file." else echo "file not exist or unknown type." fi [root@os01 dir]# ./if.sh Usage: ./if.sh <path> [root@os01 dir]# ./if.sh /etc/passwd Rgular file. [root@os01 dir]# ./if.sh /etc/sysconfig Directory.
case语句
简洁版多分支if语句;
使用场景:判断某变量的值是否为多种情形中的一种时使用;
语法:
case $VARIABLE in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
PATTERN3)
分支3
;;
...
*)
分支n
;;
esac
PATTERN可使用glob模式的通配符:
*: 任意长度的任意字符;
?: 任意单个字符;
[]: 指定范围内的任意单个字符;
a|b: 多选1;
示例:提示键入任意一个字符;判断其类型;
#!/bin/bash # read -p "Plz enter a character: " char case $char in [a-z]) echo "A character." ;; [0-9]) echo "A digit." ;; *) echo "A special character." ;; esac [root@os01 dir]# ./case.sh Plz enter a character: test A special character. [root@os01 dir]# ./case.sh Plz enter a character: 12 A special character.
原文地址:http://disheng.blog.51cto.com/2821957/1695319