结构化命令structured command:允许脚本根据条件跳过部分命令,改变执行流程。
1、if-then语句
格式1:
if command
then
commands
fi
格式2:
if command; then
commands
fi
运行if之后的command命令,如果它的退出状态码是0(该命令成功执行),那么就执行then里面的命令;如果是其它值,则执行脚本中的下一条命令。fi语句用来表示if-then语句到此结束。
#!/bin/bash
if pwd
thenecho "查看当前路径成功!"
fi
2、if-then-else语句
格式:
if command
then
commands
else
commands
fi
3、嵌套if语句
通过使用嵌套的if语句,可以在shell脚本中检查多种条件
#!/bin/bash
testuser=ln
if grep $testuser /etc/passwd
thenecho "用户$testuser存在。"echo
elseecho "用户$testuser不存在。"if ls -d /home/$testuser/thenecho "但是该用户有个路径。"fi
fi
echo "脚本运行完毕!"
4、elif语句
格式:
if command1
then
commands
elif command2
then
commands
fi
#!/bin/bash
testuser=ln
if grep $testuser /etc/passwd
thenecho "用户$testuser存在。"echo
elif ls -d /home/$testuser/
thenecho "用户$testuser不存在。"echo "但是该用户有个路径。"
fi
echo "脚本运行完毕!"
5、test命令
test命令可以在if-then语句中测试不同的条件,如果test命令中列出的条件成立,那么test命令就会退出并返回退出状态码0;若条件不成立,test命令就会退出并返回非0的退出状态码。
格式:test condition
if test condition
then
commands
fi
如果不写test命令的condition条件,那它会以非0的退出状态码退出并执行else部分的代码块。
#!/bin/bash
if test
thenecho "111"
elseecho "222"
fi
加上test命令的condition条件
#!/bin/bash
var1="Full"if test $var1
thenecho "111"
elseecho "222"
fi
如果test命令的condition返回非0退出状态码
#!/bin/bash
var1=""if test $var1
thenecho "111"
elseecho "222"
fi
6、使用方括号代替test命令
可以通过使用方括号定义测试条件。注意:第一个方括号之后和第二个方括号之前必须留有空格,否则会报错。
格式:
if [ condition ]
then
commands
fi
test命令中的condition和测试条件里的condition可以判断如下3类条件:
- 数值比较
- 字符串比较
- 文件比较
数值比较
常见数值比较如下表格所示:
n1 -eq n2 | equal,是否等于 |
n1 -ne n2 | not equal,是否不等于 |
n1 -gt n2 | greater than,是否大于 |
n1 -lt n2 | less than,是否小于 |
n1 -le n2 | less equal,是否等于小于 |
n1 -ge n2 | greater equal,是否大于等于 |
#!/bin/bash
var1=10
var2=9if [ $var1 -gt 10 ]
thenecho "good!"
elseecho "not good!"
fiif [ $var1 -eq $var2 ]
thenecho "它们相等!"
elseecho "它们不等!"
fi
字符串比较
str1 = str2 | 检查str1是否和str2相同 |
str1 != str1 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否小于str2 |
str1 > str2 | 检查str1是否大于str2 |
-n str1 | 检查str1的长度是否不为0 |
-z str1 | 检查str1的长度是否为0 |
在比较字符串的相等性时,比较测试会将所有的标点和大小写都考虑在内。
#!/bin/bash
#字符串相等或不等
test=ning
if [ $test = ning ]
thenecho "111"
elseecho "222"
fiif [ $test != Ning ]
thenecho "333"
elseecho "444"
fi
在比较字符串的大小时,大于号、小于号必须转义,否则shell会将它们看成重定向符号,将字符串的值当做文件名;另外,大于和小于顺序与sort命令所采用的不同。
在比较测试中,大写字母是小于小写字母的,但sort则相反,当你使用sort排序时,小写字母会排在前面。这是因为在比较测试中,使用的是Unicode顺序,根据每个字符的Unicode编码值来决定排序结果;sort命令使用的是系统语言环境设置中定义的排序顺序,对于英语,语言设置环境指定了小写字母在大写字母之前。
#!/bin/bash
#字符串的大于小于比较
test=yue
test1=ning
if [ $test \> $ning ]
thenecho "111"
elseecho "222"
fi#字符串的大小写比较
var1=Ning
var2=ning
if [ $var1 \> $var2 ]
thenecho "333"
elseecho "444"
fi
字符串大小
空变量和未初始化的变量会对shell脚本测试造成灾难性的影响,如果不确定变量的内容,最好在将其用于数值或字符串比较之前先通过 -n 或 -z 来判断一下变量是否为空。
#!/bin/bash
string1="yue"
string2=""#判断string1的长度是否不为0
if [ -n $string1 ]
thenecho "111"
elseecco "222"
fi#判断string2的长度是否为0
if [ -z $string2 ]
thenecho "333"
elseecho "444"
fi#判断未定义的string3的长度是否为0
if [ -z $string3 ]
thenecho "555"
elseecho "666"
fi
文件比较
文件比较是shell编程中最为强大且使用最多的比较形式,它允许测试Linux文件系统中文件和目录的状态。
-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是否存在且默认组与当前用户相同 |
file -nt file2 | 检查file1是否比file2新(比较创建日期) |
file -ot file2 | 检查file1是否比file2旧(比较创建日期) |
#!/bin/bash
#举例:检查指定对象是否为文件
object_name=$HOME
echo
echo "目标已经确认:$object_name."
echoif [ -e $object_name ]
thenecho "目标存在!"if [ -f $object_name ]thenecho "目标不仅存在,而且还是个文件。"elseecho "目标存在,但它是目录,不是文件。"fielseecho "目标不存在!"
fi
比较两个文件的创建日期时,-nt 和 -ot 都不会先检查文件是否存在,所以为了防止这一点,在比较前可以先判断两个文件是否已存在。
#!/bin/bash
#比较两个文件的创建日期if [ $HOME/Downloads/test1.sh -nt $HOME/Downloads/test2.sh ]
thenecho "test1.sh更新!"
elseecho "test2.sh更新!"
fi
7、布尔逻辑
可以使用布尔逻辑将多个测试条件组合起来。
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
#!/bin/bash
# 检查$HOME目录是否存在,且在该目录下是否存在有名为tesh.sh的文件,并且还有该文件的写权限。
if [ -d $HOME ] && [ -w $HOME/test.sh ]
thenecho "你有该文件的写权限。"
elseecho "不能对该文件进行写操作。"
fi
8、if-then的高级特性
- 在子shell中执行命令的单括号
- 用于数学表达式的双括号
- 用于高级字符串处理功能的双方括号
使用单括号
格式:(command)
在bash shell执行command之前,会先创建一个子shell,然后在其中执行命令。如果命令成功结束,则退出状态码会被设为0,接着执行then部分的代码块,反之,退出状态码不为0,则执行else代码块。
#!/bin/bash
echo $BASH_SUBSHELL #是在当前shell中执行的,输出结果是0,表明未使用子shellif (echo $BASH_SUBSHELL) #在子shell中执行的,输出结果为1,表明使用了子shell
thenecho "子shell命令操作成功!"
elseecho "子shell命令操作失败。"
fi
BASH_SUBSHELL是一个环境变量,它表示当前 shell 的子 shell 级别。每当在 Bash 中启动一个新的子 shell 时,它的值就会增加。
#在顶层 shell 中,BASH_SUBSHELL 的值通常是 0
echo $BASH_SUBSHELL # 输出: 0#启动一个子 shell, BASH_SUBSHELL 的值为1
(echo $BASH_SUBSHELL) # 输出: 1#嵌套启动多个子 shell,BASH_SUBSHELL 的值
(echo $BASH_SUBSHELL; (echo $BASH_SUBSHELL)) # 输出: 1 和 2
使用双括号
双括号命令允许在比较过程中使用高级数学表达式。
格式:(( expression ))
expression可以是任意的数学赋值或比较表达式,除了test命令使用的标准数学运算符外,还有如下所示的运算符
val++ | 后增 |
val-- | 后减 |
++val | 先增 |
--val | 先减 |
! | 逻辑取反 |
~ | 位求反 |
** | 幂运算 |
<< | 左位移 |
>> | 右位移 |
& | 位布尔AND |
| | 位布尔OR |
&& | 逻辑AND |
|| | 逻辑OR |
双括号命令既可以在if语句中使用,也可以在shell脚本中的普通命令中使用
#!/bin/bash
var1=9#双括号中的大于号不用转义
if (( $var1**2 > 80 ))
then(( var2 = $var1**2 ))echo "$var2大于$var1."
fi
使用双方括号
格式:[[ expression ]]
双方括号提供了针对字符串比较的高级特性。expression既可以使用test命令中的标准字符串比较方法,还可以进行模式匹配。在进行模式匹配时,可以定义通配符或正则表达式来匹配字符串。
#!/bin/bash
if [[ $BASH_VERSION == 5.* ]]
thenecho "你使用的bash shell版本是5系列的。"
elseecho $BASH_VERSION
fi
声明:以上内容均是学习内容,非原创。