分支循环是编程语言重要结构,它使得计算机源源不断地给搬砖。Shell 中也有对应语法支持。
在分支循环结构中,判断条件十分重要,在 Shell 中可以用test
函数来判断条件。
1 test
函数
test
在 Shell 用于测试判断,如其名字所示,它可以进行一些测试,如:
- 两个字符串是否相等
- 给定路径是否存在
- 路径是否有各种权限
- ......
语法如下:
test condition
test $a -eq 5
判断为逻辑真,返回0
,判断值为假返回值1
。返回值不能用e=$(test $a -eq 5)
来获取,这样运算后e
是空。而要用$?
的方式来获取。$?
用于获取上一条命令的返回值。
test 1 -eq 2
echo $? # output 1, which means false
test 1 -eq 1
echo $? # output 0, which means true
test
的返回值可以作为条件判断(如if else
)的条件:
if test "${a}" -eq 5; then echo $a; fi
test
命令也可以用单中括号([]
)来代替,只是使用单中括号时候,需要注意在中括号和条件之间必须有空格()。
if [ -e ex ]; then echo "exist ex"; else echo "not exist ex"; fi
if test -e ex; then echo "exist ex"; else echo "not exist ex"; fi
1.1 路径判断
Linux 中文件不一定有扩展名,文件和文件夹的名字没有区别。
函数 | 意义 |
---|---|
-e |
路径存在(文件或文件夹)则返回 true,否则 false,e 是 exist 的意思 |
-d |
路径存在且是文件夹则返回 true,否则 false,d 是 directory 的意思 |
-f |
路径存在且是文件则返回 true,否则 false,f 是 file 的意思 |
-n |
路径存在且大小不为零则返回 true,否则 false,n 是 nonzero 的意思 |
-z |
路径存在且大小为零则返回 true,否则 false,z 是 zero 的意思 |
-L /-h |
路径存在且是链接则返回 true,否则 false,L 是 link 的意思 |
-r |
路径存在且有 read 权限则返回 true,否则 false,r 是 read 的意思 |
-w |
路径存在且有 write 权限则返回 true,否则 false,w 是 write 的意思 |
-x |
路径存在且有 execute 权限则返回 true,否则 false,x 是 execute 的意思 |
if [ -e $a ]; then echo "exist $a"; fi
if [ -d $a ]; then echo "exist directory $a"; fi
if [ -f $a ]; then echo "exist file $a"; fi
if [ -n $a ]; then echo "$a is not None"; fi
if [ -z $a ]; then echo "$a is None"; fi
if [ -L $a ]; then echo "exist link $a"; fi
if [ -r $a ]; then echo "$a has read access"; fi
if [ -w $a ]; then echo "$a has write access"; fi
if [ -x $a ]; then echo "$a has execute access"; fi
1.2 文件比较
test
命令也可以用于两个文件的比较。
函数 | 意义 |
---|---|
patha -nt pathb |
patha 修改时间比pathb 新则返回 true,否则 false,nt 是 newer than 的意思 |
patha -ot pathb |
patha 修改时间比pathb 旧则返回 true,否则 false,ot 是 older than 的意思 |
patha -ef pathb |
patha 和pathb 有相同 device 和 innode number 则返回 true,否则 false |
if test $a -nt $b; then echo "$a is newer than $b"; fi
if test $a -ot $b; then echo "$a is older than $b"; fi
1.3 整数比较
下面针对的是整数判断,如果不是整数,则会报错。
函数 | 意义| |
---|---|
-eq |
两整数相等则返回 true,否则 false,eq 是 equal 的意思,若输入不是俩整数,则报错 |
-gt |
两整数前者大于后者则返回 true,否则 false,gt 是 greater than 的意思,若输入不是俩整数,则报错 |
\> |
含义同-gt ,为了和重定向符号区分,则需要转义 |
-lt |
lt 是 less than 的意思 |
\< |
同-lt |
-ge |
ge 是 greater eqaul 的意思,注意没有\>= 这种写法 |
-le |
ge 是 less eqaul 的意思,注意没有\<= 这种写法 |
if test $a -eq $b; then echo "$a eqals $b"; fi
1.4 字符串不相等判断
=
和!=
针对字符串。字符串完全相同则是相等,有一点不同则是不等。
函数 | 意义| |
---|---|
= |
两字符串相同则返回 true,否则 false,判断字符串的等号左右都是有空格的 |
!= |
两字符串不同则返回 true,否则 false,gt 是 greater than 的意思,若输入不是俩整数,则报错 |
if test $a = $b; then echo "$a eqals $b"; fi
2 分支结构
就是条件判断,在不同条件下执行不同的操作。常见有if else
,do while
,case esac
这几种。
2.1 if else
结构
if condition; then xxx; fi
if condition; then xxx; else yyy; fi
if condition_1; then xxx; elif condition_2;then yyy; else zzz; fi
2.2 case esac
结构
如果有多个选项,可以用一堆if elif else
,也可以用case esac
的结构。
这个和 c 语言中的switch case
是一样的。不过这个esac
是个什么鬼?看看if
结尾的fi
就能大雾了。🐶
语法如下:
case $x in
1) echo "select 1";;
2) echo "select 2";;
3) echo "select 3";;
*) echo "select nothing";;
esac
最后的星号*
表示啥也没有选到,默认值。最后两个分号(;;
)是跳出当前case esac
的意思,和其它语言中的break
很相似。不过 shell script 本身就是有break
和continue
关键字的,和 c 语言中的关键字是一样的。
3 循环结构
常见的循环结构有for
、while
、until
三种:
for x in xxxx;
do
xyz_operation
done
while condition:
do
xyz
done
until condition
do
xyz
done
如果要一直运行,则可以使用while true
死循环一直运行。
在
continue
是跳出当前循环,继续下一次循环的意思。
break
是跳出整个循环。
当然continue
和break
都可以在后面接一个数字n
,表示是跳出当前第n
层循环的意思。
4 条件逻辑运算
4.1 分支中的条件运算
Shell 中表达式的结果可以进行与或非逻辑连接:
函数 | 含义 |
---|---|
-a /&& |
逻辑与 |
-o /\|\| |
逻辑或 |
! |
逻辑非 |
if [ x -eq 5 ] && [ y -eq 6]; then echo "help"; fi
if test x -eq 5 && test y -eq 6; then echo "help"; fi
if ![ x -eq 5 ]; then echo "help"; fi
4.2 条件级连运算
对于命令也可以进行逻辑运算。
command_1 && command_2
这里还有一个好处,如果command_1
已经返回逻辑假,则command_2
就可以不执行了。
if [ ! -d ${path1} ]; then
mdkir -p ${path1}
fi
上面的写法就可以简写:
[ ! -d ${path1} ] && mkdir -p ${path1}
同样,对于或运算而言,如果第一个条件满足,后面的就不会执行了。这样的写法可以使代码更加简洁。
总结
本文介先绍了 Shell 中的test
命令,用于判断各种情况,然后介绍了 Shell 中的分支循环语法,以及条件级连运算。