[bash]if、test命令[ ]以及case命令

本文详细介绍了Bash脚本中的各种条件语句,包括if-then、if-then-else结构,使用test命令进行数值和字符串比较的方法,以及如何检测文件属性。还介绍了复杂的逻辑控制、数学表达式解析和高级字符串比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. if-then语句:

#!/bin/bash

if date	#所有结构化语句在跳转处使用的都是命令而不是像C语言那样的表达式,如果命令成功运行(即退出码为0)则执行then,否则就跳过then执行
then
	echo it worked!
fi

if sdfsd #无效命令返回非0
then
	echo it worked!
fi
echo not worked!
注意!fi只能终结离它最近的if


2. if-then语句的变体——使语句更接近C的风格:

#!/bin/bash

testusr=nobody
if grep $testusr /etc/passwd; then	#如果在该文件中查找到指定用户名就将该用户的目录下的bash文件
	echo The bash file for user $testusr are:
	ls -al /home/$testusr/.b*
fi

3. if-then-else语句:

#!/bin/bash

testusr=ffffff
if grep $testusr /etc/passwd
then
	echo The files for user $testusr are:
	ls -al /home/$testusr/.b*
else
	echo The user name $testusr does not exist on this system
fi

4. 使用test命令以数值比较作为条件分支:

#!/bin/bash

val1=10
val2=11

#由于由于结构化语句分支只能写命令而不能写表达式,如果需要使用表达式来进行分支则必须使用test命令
#而test命令可以是用[ ]来代替,并且在[右边和]左边必须有空格否则会报错!!
#由于bash中所有的变量都是字符串,变量名仅仅是一个宏而已,因此=、!=之类的比较都是字符串之间的比较
#因此需要做整数值比较必须使用命令将这些字符串先转化为整数然后再作数值之间的比较
#这就是test命令的选项,比如-gt、-eq等,用了这些选项就能是test命令知道要比较的是数值而不是字符串
#如果test命令中的比较关系成立则test命令返回0表示顺利执行,这也就达到了利用test命令进行比较条件分支的目的

if [ $val1 -gt 5 ]  #注意中括号内侧需要空格隔开!!
then
	echo The test value $val1 is greater then 5
fi

if [ $val1 -eq $val2 ]
then
	echo The values are equal
else
	echo The values are different
fi

#bash不支持浮点数,因此在做条件测试的时候不能使用浮点数否则会报错,因为bash会将一个浮点数作为字符串处理
#因此会直接报错
if [ 3.234 -gt 2 ]
then
	echo good!
else
	echo bad!
fi

test的比较命令选项有:

-gt: greater than

-ge: greater or equal

-lt: less than

-le: less or equal

-eq: equal

-ne: not equal


5. =、!=、<、>等的比较才是字符串的比较,因为bash是一个比较低级的解释器,所有数据都是字符串字面值:

#!/bin/bash

usrname=lirx_t_una
if [ $USER = $usrname ]
then
	echo Welcome $usrname
else
	echo You are not current user
fi

if [ $USER != hahaha ]
then
	echo You are not hahaha
fi

if [ abc \< bbb ]	#按照ASCII码进行比较,并且必须使用转移,否则会当成重定向,bash的命令无处不在!
then
	echo abc \< bbb	#echo命令中的内容如果不想被bash理解成重定向也必须使用转义字符
fi

注意sort命令不是按照字符串的ASCII大小进行比较的,而是按照系统本地化语言设置中的定义进行比较的,规定小写字母排在大写字母之前而ASCII是大写字母排在小写字母之前!

!当一个字符串中包含有命令符号(比如重定向符号'<'等),如果字符串不用引号引起来则会被bash当成命令看待,因此必须使用转义符号将其解释为普通字符,否则就直接用引号将字符串引起来,这样里面的命令符号就会被看做是普通符号了,比如echo abc \< bbb,或者echo 'abc < bbb',两者是等价的;


6. 利用-n和-z选项判断字符串是否为空:

#!/bin/bash

#判断一个字符串是否为空
#-n判断是否为非空,-z判断是否为空

s1=testing
s2=

if [ -n $s1 ]
then
	echo "The string '$s1' is not empty"    #为了显示'',必须使用""将整个字符串括起来!
else
	echo "The string '$s1' is empty"
fi

if [ -z $s2 ]
then
	echo "The string '$s2' is empty"
else
	echo "The string '$s2' is not empty"
fi

if [ -z $s3 ]
then
	echo "The string '$3' is empty"
else
	echo "The string '$3' is not empty"
fi

7. 利用test命令的选项来检测文件:

#!/bin/bash

if [ -d $HOME ]	#检查指定的目录是否存在,注意,一定是目录!
then
	echo Your HOME directory exists
	cd $HOME
	ls -al | more
else
	echo There is a problem with your HOME directory
fi

if [ -e $HOME ]	#检查指定文件或目录(即广义上的对象)是否存在
then
	echo OK on the HOME directory. Now check the file:
	if [ -e $HOME/testing ]
	then
		echo Appending date to existing file
		date >> $HOME/testing
	else
		echo Creating new file and write date to it
		date > $HOME/testing
	fi
else
	echo There is a problem with your HOME directory
fi

if [ -e $HOME ]
then
	echo HOME is exist, but is it a file?
	if [ -f $HOME ]	#检查是否为一文件,必须是文件而不是目录!
	then
		echo Yes, it is
	else
		echo "No, it isn't"
		echo But is HOME/.bash_history a file?
		if [ -f $HOME/.bash_history ]
		then
			echo "Yes, it is"
		fi
	fi
else
	echo There is a problem with your HOME directory
fi

fshdw=/etc/shadow	#影子文件保存用户密码,普通用户没有权限访问
if [ -f $fshdw ]	#判断一个文件是否具有读权限
then
	if [ -r $fshdw ]	#判断一个文件是否具有读权限
	then
		tail $fshdw
	else
		echo Unable to read the $fshdw file
	fi
else
	echo "The $fshdw doesn't exist"
fi

file=kk
touch $file

if [ -s $file ]	#检测文件中是否有数据,若有则test返回0,在做这些事之前要先判是否存在,test只看返回值
then
	echo $file exists and has data in it
else
	echo $file exists and is empty
fi

date >> $file
if [ -s $file ]	
then
	echo $file exists and has data in it as it shows:
	cat $file
else
	echo $file exists and is empty
fi

logfile=$HOME/logtest
touch $logfile
now=`date +%y%m%d-%H%M`

chmod u-w $logfile	#先移除用户对文件的写权限
if [ -w $logfile ]
then
	echo The program ran at: $now >> $logfile
	echo The first attempt succeed!
else
	echo The first attempt failed!
fi

chmod u+w $logifle	#在赋予用户对文件的写权限
echo hahahhah
if [ -w $logfile ]
then
	echo The program ran at: $now >> $logfile
	echo The second attempt succeed!
else
	echo The second attempt failed!
fi

if [ -x ./a.out ]	#检查一个文件是否具有可执行的权限
then
	echo You can run the program
else
	echo You are unable to run the program
fi

file=/etc/passwd
if [ -O $file ]	#检查当前用户是否是本文件的属主,可以用su命令切换成root进行测试
then
	echo You are the owner of $file
else
	echo You are not the owner of $file
fi

8. 通过-nt和-ot选项比较两个文件的新旧:

#!/bin/bash

f1=./a.out
f2=./test.c

#注意!比较之前一定要先判是否存在,否则会返回错误的比较结果
#也就是说即使不存在的文件也是可以比较的,只不过结果肯定是你不想要的

if [ $f1 -nt $f2 ]	#newer than,判断前者是否新于后者
then
	echo $f1 is newer than $f2
else
	echo $f2 is newer than $f1
fi

if [ $f1 -ot $f2 ]	#older than,判断前者是否旧于后者
then
	echo $f1 is older than $f2
else
	echo $f2 is older than $f1
fi

9. 与或连接实现复杂逻辑控制:

可以用&&和||运算符连接多个test命令:

#!/bin/bash

if [ 132 -gt 32 ] && [ 32 -ne 333 ]
then
	echo Yes
else
	echo No
fi

if [ 22 -eq 333 ] || [ 23 -gt 1 ]
then
	echo Yes
else
	echo No
fi

a=324
if [ 32 -eq 324 ] && a=sdkfjs	#具有短路特性,因此要小心副作用
then
	echo fuck
fi
echo $a

a=324
if [ 324 -eq 324 ] && a=sdkfjs	#具有短路特性
then
	echo fuck
fi

#应用实例:
if [ -d $HOME ] && [ -w test.c ]
then
	echo The file exists and you can write it
else
	echo You cannot write to the file
fi

10. (())命令——可以像C语言那样实现高级的数学表达式:

#!/bin/bash

if ((0))	#支持C语言式的条件检测,即0为false,非0为true
then
	echo not zero
else
	echo zero
fi

if (( -234 ))	#里面的空格可以随意加
then
	echo not zero
fi

a=0
if (( !$a ))
then
	echo zero
fi

b=14
c=12
(( c = $b * $c ))	#可以实现大多数C语言的运算,除了复合运算符+=等不能使用
echo $c
(( c = $c << 1 ))
echo $c
(( c = $b & $c ))
echo $c

if (($b ** 2 > 15 ** 2))	#同样也可以实现比较,并且增加了幂运算**
then
	echo bigger
else
	echo less
fi

(())也支持==、!=等C语言中的操作;

!我们可以形象将(())称为C语言表达式解析命令,因为它可以解析几乎所有的C语言常见的表达式,比如:

if (($a == 15 && 20 < 30 || !$var))等,不仅可以将表达式用于bash的条件判断,也可以用作普通的表达式运算!

!注意:(())是一条命令,不可以错误的认为可以将里面的运算结果返回给某个变量,因为既然它是命令,那么它返回的只可能是命令是否执行成功的返回码,比如:

a=((15*8))是错误的,必须写成((a = 15 * 8));

!该命令会将括号中的纯数字字符串解析成数,将其余带字母的字符串解析成变量名!这是显而易见的!


11. [[]]命令——支持类似C++的高级字符串比较(同时支持正则表达式等模式匹配):

#!/bin/bash

name=hash
if [[ $name == h* ]]	#空号两侧必须加空格否则会报错!
then
	echo Yes you are
else
	echo No you are not
fi

12. 嵌套if和case分支:

#!/bin/bash

if [ $USER = haha ]
then
	echo You are haha
elif [ $USER = hoho ]	#就是else if的缩写
then
	echo You are hoho
elif [ $USER = hihi ]
then
	echo You are hihi
else
	echo You are nothing
fi

case $USER in	#case XXX in的格式
	haha | hoho)	#用)表示一个选项
		echo You are haho;;		#末尾一定要用两个;表示一个选项的结束
	hehe)
		echo You are hehe;;
	hihi)
		echo You are hihi;;
	*)							#*)表示默认选项
		echo You are nothing;;
esac	#表示退出case分支
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值