Shell结构化命令
概要: 学习Shell(1) 结构化指令,if-then, test, case
创建时间: 2022.08.01 23:07:13
更新时间: 2023.08.16 22:32:26
本文结构

if-then语句
if-then语句
基本语法
示例
Bash |
---|
| #!/bin/bash
if pwd
then
echo "OK!"
echo "It worked"
fi
|

注意
- 当
if
后的条件判断语句 cmd
成功结束(退出码为0)后,将执行 then
后的 cmds
语句
cmds
语句可以包含多条shell命令
- 以上 if-then 语法还可以写为如下形式
if-then-else语句
基本语法
Bash |
---|
| if cmd
then
cmds1
else
cmds2
fi
|
在上面的语法中,如果 if
后的 cmd
返回状态码0,那么执行 then
部分语句。但如果返回非零状态码,将会执行 else
部分的命令。
Bash |
---|
| #!/bin/bash
testUser=NoSuchUser
if grep $testUser /etc/passwd
then
echo "Find user $testUser!"
else
echo "Not found user $testUser."
fi
|
嵌套if语句
下面的脚本用于检测用户是否存在系统中,如果不存在系统中的话,其目录有无被清理。
Bash |
---|
| #!/bin/bash
testUser=NoSuchUser
if grep $testUser /etc/passwd
then
echo "Find user $testUser!"
else
echo "Not found user $testUser."
if ls -d /Users/$testUser
then
echo "However, $testUser has a directory!"
fi
fi
|

但上面的脚本使用嵌套 if
的方式,并不便于维护,推荐使用如下的 if-elif-fi
形式(else
语句可选)
Bash |
---|
| if cmd1
then
cmds1
elif cmd2
then
cmds2
else
cmds3
fi
|
改写后的脚本如下
Bash |
---|
| #!/bin/bash
testUser=NoSuchUser
if grep $testUser /etc/passwd
then
echo "Find user $testUser!"
elif ls -d /Users/$testUser
then
echo "Not found user $testUser."
echo "However, $testUser has a directory!"
fi
|
test语句
在普通的 if
语句中,if-then
只能测试命令退出状态码,并不支持如数学运算等其他操作,不过 test
语句可以测试条件语句,语法如下
在 if-then
语句中表示为
Bash |
---|
| if test condition
then
cmds
fi
|
或者写为如下形式
Bash |
---|
| if [ condition ]
then
cmds
fi
|
condition
是 test
命令要测试的一系列参数和值
举例如下,可以使用 test
判断是否为空字符串
Bash |
---|
| #!/bin/bash
str="string"
if test $str
then
echo "True"
else
echo "False"
fi
|
数值比较
参考下表

简单的测试脚本如下
Bash |
---|
| #!/bin/bash
x=5
if [ $x -gt 3 ]
then
echo "x >= 3"
fi
|

注意:bash shell 只能处理整数
字符串比较
参考下表

字符串相等比较
Bash |
---|
| #!/bin/bash
testUser=lzwang
if [ $USER = $testUser ]
then
echo "Welcome $testUser"
fi
|
字符串顺序比较
Bash |
---|
| #!/bin/bash
var1=baseball
var2=pingpong
if [ $var1 \> $var2 ]
then
echo "$var1 is greater than $var2"
else
echo "$var1 is less than $var2"
fi
|

注意
- 大于和小于号必须转义,否则shell将把它们作为重定向符号,且把字符串值当作文件名
- 不同字母,越靠后越大
- 相同字母,大写字母比小写字母小(和
sort
命令相反)
字符串大小比较
Bash |
---|
| #!/bin/bash
var1=test
var2=''
if [ -n $var1 ]
then
echo "String '$var1' is not empty"
fi
if [ -z $var2 ]
then
echo "String '$var2' is empty"
fi
if [ -z $var3 ]
then
echo "String '$var3' is empty"
fi
|

注意
- 未定义过的变量在shell中长度为0
文件比较

检查对象是否存在和类型
Bash |
---|
| #!/bin/bash
item=$HOME
if [ -e $item ]
then
echo "item $item does exist"
if [ -d $item ]
then
echo "item $item is a directory"
elif [ -f $item ]
then
echo "item $item is a file"
fi
else
echo "item $item does not exist"
fi
|
检查空文件
Bash |
---|
| #!/bin/bash
item=$HOME/playground/test_file
touch $item
if [ -s $item ]
then
echo "item $item has data"
else
echo "item $item has no data"
fi
|

注意:当被检查文件有数据时,-s
返回值为真
检查文件权限
下面的脚本检测文件的读写和执行权限
Bash |
---|
| #!/bin/bash
item=$HOME/playground/test_file
if [ -r $item ]
then
echo "$item is readable"
fi
if [ -w $item ]
then
echo "$item is writable"
fi
if [ -x $item ]
then
echo "$item is executable"
fi
|
检查文件归属
下面的脚本检测文件是否属于当前用户或者当前用户组
Bash |
---|
| #!/bin/bash
item=$HOME/playground/test_file
if [ -O $item ]
then
echo "$item is owned by $USER"
fi
if [ -G $item ]
then
echo "$item is owned by $USER group"
fi
|
检查文件日期
Bash |
---|
| #!/bin/bash
file2=$HOME/playground/testfile2
file3=$HOME/playground/testfile3
if [ $file3 -nt $file2 ]
then
echo "$file3 is newer than $file2"
fi
if [ $file2 -ot $file3 ]
then
echo "$file2 is old than $file3"
fi
|

注意,在比较文件时间戳时,-nt
表示 newer than,-ot
表示 older than
复合条件测试
Bash |
---|
| # and
[ condition1 ] && [ condition2 ]
# or
[ condition1 ] || [ condition2 ]
|
示例略
双圆括号
双圆括号主要用于高级数学表达式,提供了更多的运算方式,如下表所示
Bash |
---|
| #!/bin/bash
var1=10
if (( $var1 ** 2 > 90 ))
then
(( var2 = $var1 ** 2 ))
echo "The square of $var1 is $var2"
fi
|
双方括号
双方括号提供了高级字符串比较表达式,也称为模式匹配
Bash |
---|
| #!/bin/bash
if [[ $USER == lz* ]]
then
echo "Hello, $USER"
fi
|
case语句
case
语句用于简化过多的 elif
语句,语法模式如下
Bash |
---|
| case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
|
简单示例如下
Bash |
---|
| #!/bin/bash
case $USER in
daidai | duouo)
echo "Welcome, guest $USER";;
lzwang)
echo "Welcome, master $USER";;
*)
echo "$USER has no permission to visit.";;
esac
|

注意
- case 命令将指定的变量与不同的模式相匹配,如果匹配则执行此模式下指定的命令
- 可以通过竖线操作符在一行中分隔出多个模式,只要有一个匹配上就执行此组模式下的命令
- 最终的星号捕获其他所有与已知模式不匹配的值
参考