Linux shell 学习笔记(8)— 使用结构化命令(if-then 语句、数值比较、字符串比较、文件比较、case 语句)

1. 使用 if-then 语句

最基本的结构化命令就是if-then语句。if-then语句有如下格式。

if 	command
then
​	commands
fi

或者

if 	command; then
​	commands
fi

bash shell 的 if 语句会运行 if 后面的那个命令。如果该命令的退出状态码是 0(该命令成功运行),位于 then 部分的命令就会被执行。如果该命令的退出状态码是其他值, then 部分的命令就不会被执行,bash shell 会继续执行脚本中的下一个命令。fi 语句用来表示 if-then 语句到此结束。

$ cat test1.sh
#!/bin/bash
# testing the if statement
if pwd
then
echo "It worked"
fi
$

执行结果

$ ./test1.sh
/home/Christine
It worked
$

在 then 部分,你可以使用不止一条命令。可以像在脚本中的其他地方一样在这里列出多条命令。bash shell 会将这些命令当成一个块,如果 if 语句行的命令的退出状态值为 0,所有的命令都会被执行;如果 if 语句行的命令的退出状态不为 0,所有的命令都会被跳过。

2. if-then-else 语句

if-then-else 语句在语句中提供了另外一组命令。

if 	command
then
​	commands
else
​	commands
fi

当if语句中的命令返回退出状态码 0 时,then 部分中的命令会被执行,这跟普通的 if-then 语句一样。当 if 语句中的命令返回非零退出状态码时,bash shell 会执行 else 部分中的命令。

3. 嵌套 if 语句

elif 使用另一个 if-then 语句延续 else 部分。

if 	command1
then
	commands
elif 	command2
then
	more commands
fi

elif 语句行提供了另一个要测试的命令,这类似于原始的 if 语句行。如果 elif 后命令的退出状态码是 0,则 bash 会执行第二个 then 语句部分的命令。

$ cat test5.sh
#!/bin/bash
# Testing nested ifs - use elif
#
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
then
	echo "The user $testuser exists on this system."
#
elif ls -d /home/$testuser
then
	echo "The user $testuser does not exist on this system."
	echo "However, $testuser has a directory."
#
fi
$
$ ./test5.sh
/home/NoSuchUser
The user NoSuchUser does not exist on this system.
However, NoSuchUser has a directory.
$

可以继续将多个 elif 语句串起来,形成一个大的 if-then-elif 嵌套组合。

if 	command1
then
	command set 1
elif 	command2
then
	command set 2
elif 	command3
then
	command set 3
elif	 command4
then
	command set 4
fi

每块命令都会根据命令是否会返回退出状态码 0 来执行。记住,bash shell 会依次执行if语句,只有第一个返回退出状态码 0 的语句中的 then 部分会被执行。

4. test 命令

test 命令提供了在 if-then 语句中测试不同条件的途径。如果 test 命令中列出的条件成立,test 命令就会退出并返回退出状态码 0。如果条件不成立,test 命令就会退出并返回非零的退出状态码,这使得 if-then 语句不会再被执行。

test 命令的格式非常简单。

test condition

condition 是 test 命令要测试的一系列参数和值。如果不写 test 命令的 condition 部分,它会以非零的退出状态码退出,并执行 else 语句块。

$ cat test6.sh
#!/bin/bash
# Testing the test command
#
if test
then
	echo "No expression returns a True"
else
	echo "No expression returns a False"
fi
$
$ ./test6.sh
No expression returns a False
$

当你加入一个条件时,test 命令会测试该条件。例如,可以使用 test 命令确定变量中是否有内容。这只需要一个简单的条件表达式。

$ cat test6.sh
#!/bin/bash
# Testing the test command
#
my_variable="Full"
#
if test $my_variable
then
	echo "The $my_variable expression returns a True"
#
else
	echo "The $my_variable expression returns a False"
fi
$
$ ./test6.sh
The Full expression returns a True
$

bash shell 提供了另一种条件测试方法,无需在 if-then 语句中声明 test 命令。

if 	[ condition ]
then
​	commands
fi

方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。

test 命令可以判断三类条件:

  • 数值比较
  • 字符串比较
  • 文件比较

4.1 数值比较

记住,bash shell只能处理整数

比较操作描述
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
$ cat numeric_test.sh
#!/bin/bash
# Using numeric test evaluations
#
value1=10
value2=11
#
if [ $value1 -gt 5 ]
then
	echo "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
then
	echo "The values are equal"
else
	echo "The values are different"
fi
#
$
#	运行结果
$ ./numeric_test.sh
The test value 10 is greater than 5
The values are different
$

4.2 字符串比较

比较操作描述
str1 = str2检查str1是否和str2相同
str1 != str2检查str1是否和str2不同
str1 < str2检查str1是否比str2小
str1 > str2检查str1是否比str2大
-n str1检查str1的长度是否非0
-z str1检查str1的长度是否为0
  1. 检查字符串相等性

    $ cat test7.sh
    #!/bin/bash
    # testing string equality
    testuser=rich
    #
    if [ $USER = $testuser ]
    then
    	echo "Welcome $testuser"
    fi
    $
    $ ./test7.sh
    Welcome rich
    $
    
  2. 字符串大小

    $ cat test10.sh
    #!/bin/bash
    # testing string length
    val1=testing
    val2=''
    #
    if [ -n $val1 ]
    then
    	echo "The string '$val1' is not empty"
    else
    	echo "The string '$val1' is empty"
    fi
    #
    if [ -z $val2 ]
    then
    	echo "The string '$val2' is empty"
    else
    	echo "The string '$val2' is not empty"
    fi
    #
    if [ -z $val3 ]
    then
    	echo "The string '$val3' is empty"
    else
    	echo "The string '$val3' is not empty"
    fi
    $
    $ ./test10.sh
    The string 'testing' is not empty
    The string '' is empty
    The string '' is empty
    $
    

    空的和未初始化的变量会对shell脚本测试造成灾难性的影响。如果不是很确定一个变量的内容,最好在将其用于数值或字符串比较之前先通过-n或-z来测试一下变量是否含有值。

4.3 文件比较

比较描述
-d file检查file是否存在并是一个目录
-e file检查file是否存在
-f file检查file是否存在并是一个文件
-r file检查file是否存在并可读
-s file检查file是否存在并非空
-w file检查file是否存在并可写
-x file检查file是否存在并可执行
-O file检查file是否存在并属当前用户所有
-G file检查file是否存在并且默认组与当前用户相同
file1 -nt file2检查file1是否比file2新 (但不会检查文件是否存在)
file1 -ot file2检查file1是否比file2旧 (但不会检查文件是否存在)
$ cat test11.sh
#!/bin/bash
# Look before you leap
#
jump_directory=/home/arthur
#
if [ -d $jump_directory ]
then
	echo "The $jump_directory directory exists"
	cd $jump_directory
	ls
else
	echo "The $jump_directory directory does not exist"
fi
#
$
$ ./test11.sh
The /home/arthur directory does not exist
$

5. 复合条件测试

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

  • [ condition1 ] && [ condition2 ]

    两个条件都必须满足

  • [ condition1 ] || [ condition2 ]

    任意一个条件满足

$ cat test22.sh
#!/bin/bash
# testing compound comparisons
#
if [ -d $HOME ] && [ -w $HOME/testing ]
then
	echo "The file exists and you can write to it"
else
	echo "I cannot write to the file"
fi
$
$ ./test22.sh
I cannot write to the file
$
$ touch $HOME/testing
$
$ ./test22.sh
The file exists and you can write to it
$

6. if-then 高级特性

bash shell 提供了两项可在 if-then 语句中使用的高级特性:

  • 用于数学表达式的双括号
  • 用于高级字符串处理功能的双方括号

6.1 使用双括号

双括号命令允许你在比较过程中使用高级数学表达式。test 命令只能在比较中使用简单的算术操作。

双括号命令的格式如下:

**(( expression ))**

expression 可以是任意的数学赋值或比较表达式,双括号命令符号如下表所示

符号描述
val++后增
val–后减
++val先增
–val先减
!逻辑求反
~位求反
**幂运算
<<左位移
>>右位移
&位布尔和
|位布尔或
&&逻辑和
||逻辑或

可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。

$ cat test23.sh
#!/bin/bash
# using double parenthesis
#
val1=10
#
if (( $val1 ** 2 > 90 ))
then
	(( val2 = $val1 ** 2 ))
	echo "The square of $val1 is $val2"
fi
$
$ ./test23.sh
The square of 10 is 100
$

**注意,不需要将双括号中表达式里的大于号转义。**这是双括号命令提供的另一个高级特性。

6.2 使用双方括号

多数情况下 [ ][[ ]] 是可以通用的,两者的主要差异是: test[ ] 是符合 POSIX 标准的测试语句,兼容性更强,几乎可以运行再所有的 Shell 解释器中,相比较而言 [[ ]] 仅可运行再特定的几个 Shell 解释器中(如 Bash/Zsh 等)。事实上,目前支持使用 [[ ]] 进行条件测试的解释器已经足够多了。使用 [[ ]] 进行测试判断时甚至可以使用正则表达式。

双方括号命令提供了针对字符串比较的高级特性。双方括号命令的格式如下:

[[ expression ]]

双方括号里的 expression 使用了 test 命令中采用的标准字符串比较。但它提供了 test 命令未提供的另一个特性——模式匹配(pattern matching)。

$ cat test24.sh
#!/bin/bash
# using pattern matching
#
if [[ $USER == r* ]]
then
	echo "Hello $USER"
else
	echo "Sorry, I do not know you"
fi
$
$ ./test24.sh
Hello rich
$

比较

7. case 命令

case 命令会采用列表格式来检查单个变量的多个值:

case variable in
pattern1 | pattern2) 	commands1;;
pattern3) 				commands2;;
*) 					default commands;;
esac

case 命令会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么 shell 会执行为该模式指定的命令。可以通过竖线操作符在一行中分隔出多个模式模式。星号会捕获所有与已知模式不匹配的值。

$ cat test26.sh
#!/bin/bash
# using the case command
#
case $USER in
rich | barbara)
	echo "Welcome, $USER"
	echo "Please enjoy your visit";;
testing)
	echo "Special testing account";;
jessica)
	echo "Do not forget to log off when you're done";;
*)
	echo "Sorry, you are not allowed here";;
esac
$
$ ./test26.sh
Welcome, rich
Please enjoy your visit
$	
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值