shell编程----if-test


1. if-test

  test是shell内置命令,用来检测某个条件是否成立。test通常和if语句一起使用,并且大部分if语句都依赖test。
  test命令有很多选项,可以进行数值、字符串和文件三个方面的检测。
  shell test 命令的用法为:test expression
  当test判断expression成立时,退出状态为0,否则为非零值。
  test命令也可以简写为[],他的用法为:[ expression ],注意[]和expression之间的空格,这两个空格时必须的,否则会导致语法错误。[]的写法更加简洁,比test使用频率高。
  test命令可以判断3类条件:数值比较,字符串比较,文件比较。

2. test的数值比较

test命令的数值比较功能

比较 描述
n1 -eq n2 检查n1是否与n2相等
n1 -ge n2 检查n1是否大于或等于n2
n1 -gt n2 检查n1是否大于n2
n1 -le n2 检查n1是否小于或等于n2
n1 -lt n2 检查n1是否小于n2
n1 -ne n2 检查n1是否不等于n2
#!/bin/bash
# 数值条件测试可以用在数字和变量上
read val
read val1

if [ $val -eq $val1 ]
then
	echo "The test value $val is equal $val1"
elif [ $val -gt $val1 ]
then
	echo "The test value $val is greater than $val1"
else
	echo "The test value $val is lower than $val1"
fi

结果:
12
33
The test value 12 is lower than 33
33
33
The test value 33 is equal 33

注意:不能在test中使用符点值

3. test的字符串比较

比较 描述
str1 = str2 检查str1是否和str2相同
str1 != str2 检查str1是否和str2不同
str1 < str2 检查str1是否比str2小
str1 > str2 检查str1是否比str2大
-n str1 检查str1的长度是否非0
-z str1 检查str1的长度是否为0

$USER的用法:

[kiosk@foundation60 ~]$ echo $USER
kiosk
#!/bin/bash
# 字符串的相等性
# 比较字符串相等性的时候,test的比较会将所有的标点和大写也考虑在内

luser=root

if [ $USER=$luser ]
then
	echo "登录成功"
else
	echo "登录失败"
fi

结果:
登录成功

# 大于小与符号必须转义
# 否则shell会把他们当作重定向符号,从而把字符串当作文件名

val1=zjy
val2=ljl

if [ $val1 \> $val2 ];then
	echo "$val1 is greater than $val2"
else
	echo "$val1 is less than $val2"
fi

结果:
zjy is greater than ljl

==注意:==字符串的比较遵循字典顺序,规则如下:如果第一个字符串是第二个字符串的前缀,那么第一个小,比如a小于about。从字符串的开头比较,按照字母顺序,a比b小,比如about小于ball。如果第一个字符相同,在比较第二个,比如about小于above。总之,如果你查字典,字典排在前面的单词比后面的单词小。

#!/bin/bash
# 注意:没有被定义的值也会有输出结果
val1=zjy
val2=''

if [ -n $val1 ];then
	echo "$val1 is not empty"
else
	echo "$val1 is empty "
fi

if [ -z $val2 ];then
        echo "'$val2' is empty"
else
        echo "'$val2' is not empty "
fi

if [ -z $val3 ];then
        echo "'$val3' is empty"
else
        echo "'$val3' is not empty "
fi

结果:
zjy is not empty
‘’ is empty
‘’ is empty

4. 文件比较

比较 描述
-d file 检查file是否存在并是一个目录
-e file 检查file是否存在
-f file 检查file是否存在并是一个文件
-r file 检查file是否存在并可读
-s file 检查file是否存在并非空
-w file 检查file是否存在并可写
-x file 检查file是否存在并可执行
-O file 检查file1是否存在并属于当前用户所有
-G file 检查file是否存在并且默认组与当前用户相同\
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
#!/bin/bash

if [ -d $HOME ];then
	echo "your HOME directory exits"
	cd $HOME
	ls -a
else
	echo "There is a problem with your HOME diretory"
fi

结果:
your HOME directory exits
. .bashrc Downloads .mozilla .ssh
… .cache .esd_auth Music .tcshrc
anaconda-ks.cfg .config .gnome2 Pictures Templates
.bash_history .cshrc .gnome2_private Public Videos
.bash_logout Desktop .ICEauthority redhat_iso7.3 .viminfo
.bash_profile Documents .local shell

#!/bin/bash
if [ -e $HOME ]
then 
	echo "ok on the directory.now to check the file"
	if [ -e $HOME/testing ]
	then
		echo "appending date to exiting file"
date >> $HOME/testing  # 表示追加正确输出
	else
		echo "creating new file"
		date > $HOME/testing   # 表示重定向正确输出
	fi
else
	echo "sorry,you do not have a HOME directory"
fi

结果:
ok on the directory.now to check the file
creating new file

#!/bin/bash
if [ -e $HOME ];then
	echo "the object exists.is it a file?"
	if [ -f $HOME ];then
		echo "yes,it is a file."
	else
		echo "no,it is not a file."
		if [ -f $HOME/.bash_history ]
		then
			echo "but this is a file."
		fi
	fi
else
	echo "sorry,the object does not exist."
fi

结果:
the object exists.is it a file?
no,it is not a file.
but this is a file.

#!/bin/bash
file=/etc/shadow
if [ -f $file ];then
	if [ -r $file ];then
		tail $file
	else
		echo "sorry,i am unable to read the $file file"
	fi
else
	echo "sorry,the file $file does not exist."
fi

结果:
saslauth:!!:16442::::::
ntp:!!:16442::::::
rtkit:!!:16442::::::
radvd:!!:16442::::::
pulse:!!:16442::::::
gdm:!!:16442::::::
gnome-initial-setup:!!:16442::::::
tcpdump:!!:16442::::::
apache:!!:18301::::::
dhcpd:!!:18301::::::

#!/bin/bash

file=stest
touch $file

if [ -s $file ];then
	echo "the $file exists and has data in it"
else
	echo "the $file exists and is empty"
fi

结果:
the stest exists and is empty
the stest exists and has data in it

#!/bin/bash
logfile=testroot
touch $logfile
now=`date +%Y%d-%H%M`

if [ -w $logfile ];then
	echo "the program ran at:$now" > $logfile
	echo "the first attempt succeeed"
else
	echo "the first attempt failed"
fi

chmod u+w $logfile
if [ -w $logfile ];then
	echo "the program ran at:$now" > $logfile
	echo "the second attempt succeeed"
else
	echo "the second attempt failed"
fi

结果:
testroot
the program ran at:202012-0932

#!/bin/bash
if [ -x test05.sh ];then
	echo "you can run the scrip"
	./test05.sh
else
	echo "sorry,you are unable to execute the script"
fi

结果:
[root@localhost 2-12]# sh test11.sh
sorry,you are unable to execute the script
[root@localhost 2-12]# chmod +x test05.sh
[root@localhost 2-12]# sh test11.sh
you can run the scrip
your HOME directory exits
. .bashrc Downloads .mozilla .ssh
… .cache .esd_auth Music .tcshrc
anaconda-ks.cfg .config .gnome2 Pictures Templates
.bash_history .cshrc .gnome2_private Public testing
.bash_logout Desktop .ICEauthority redhat_iso7.3 Videos
.bash_profile Documents .local shell .viminfo

#!/bin/bash

if [ -O /etc/passwd ]
then
	echo "you are the owner if the /etc/passwd file"
else
	echo "sorry,you are not the owner of the /etc/passwd file"
fi

结果:
you are the owner if the /etc/passwd file

#!/bin/bash

if [ -G /etc/passwd ]
then
	echo "you are the group if the /etc/passwd file"
else
	echo "sorry,you are not the group of the /etc/passwd file"
fi

结果:
you are the group if the /etc/passwd file

#!/bin/bash
if [ test01.sh -nt test02.sh ]
then
	echo "test01.sh is newer than test02.sh"
else
	echo "test02.sh is newer than test01.sh"
fi

if [ test03.sh -ot test04.sh ]
then
        echo "test03.sh is older than test04.sh"
else
        echo "test04.sh is older than test03.sh"
fi

结果:
test02.sh is newer than test01.sh
test03.sh is older than test04.sh

5. 复合条件测试

if–then语句允许你使用布尔逻辑来组合测试,有两种布尔运算符可用:

[ condition ] && [ condition2 ]  # 逻辑与
[ condition ] || [ condition2 ]    # 逻辑或
#!/bin/bash
if [ -d $HOME ] && [ -w $HOME/testing ]
then
	echo "the file exixts and you can write to it"
else
	echo "i cannot write to the file"
fi

结果:
the file exixts and you can write to it

6. if-then的高级特性

使用双尖括号(())
使用方括号[ ]

#!/bin/bash

if [[ $USER == r* ]];then
	echo "hello,$USER"
else
	echo "sorry,i do not know you"
fi

结果:
hello,root

  在test中使用变量建议用双引号包围起来。
  test和[]都是命令,一个命令本质上对应一个程序或者一个函数。即使是一个程序,它也有入口函数,例如c语言程序的入口函数是main(),运行c语言程序就从main()函数开始,所以也可以将一个程序等效为一个函数,这样我们就不用再区分函数和程序了,直接将一个命令和一个函数对应起来即可。
  有了以上认知,就很容易看透命令的本质了:使用一个命令其实就是调用一个函数,命令后面附带的选项和参数最终都会作为实参传递给函数。
  假设test命令对应的函数是func(),使用test -z $str1命令时,会先将变量$str1替换成字符串;  如果 $str1 是一个正常的字符串,比如abc123,那么替换后的效果就是test -z abc123,调用func()函数的形式就是func(-z abc123).test命令后面附带的所有选项和参数会被看成一个整体,并作为实参传递进函数。如果$str1是一个空的字符串,那么替换后的效果就是test -z,调用func()函数的形式就是func(“-z ”),这就比较奇怪了,因为-z选项没有和参数成对出现,func()在分析时就会出错。
  如果我们给$str1变量加上双引号,当$str1是空字符串时,test -z “$str1”就会被替换为test -z “”,调用func()函数的形式就是func(“-z \”\””),很显然,-z选项后面跟的是一个空字符串(\“表示转义字符”),这样func()在分析时就不会出错了。
总结:
  test命令比较奇葩,>、<、==只能用来比较字符串,不能用来比较数字,比较数字需要使用-eq、-gt等选项;不管是比较字符串还是数字。test都不支持>=和<=。有经验的程序员需要慢慢习惯test命令的这些奇葩用法。
  对于整形数字比较,我建议大家使用(()),(())支持各种运算符,写法也符合数学规则,用起来更加方便。注意:test命令使用标准的数学比较符号来表示字符串比较而用文本代码来表示数值比较,这个细微的特性会被很多程序员理解反了,如果你为数值使用了数学运算符,shell会将他们当成字符串,可能无法产生正确的结果。

发布了106 篇原创文章 · 获赞 1 · 访问量 2354

猜你喜欢

转载自blog.csdn.net/weixin_43384009/article/details/104315348