第十一章 构建基础脚本
11.1 使用多个命令
1 |
data; who; ... |
11.2 创建shell脚本文件
第一行必须要指定使用的shell,格式如下
1 |
#!/bin/bash |
一般#用作注释行,但脚本文件的第一行是个例外 #后的感叹号会告诉shell用哪个shell来运行脚本
在指明shell之后,可以在文件的各行输入命令,每行末尾加一个换行符
1 2 3 4 |
#!/bin/bash # This script displays the date and who's logged on date who |
将以上文本保存到文件test1
要使shell找到脚本可采用以下两种方法
- 将放置shell脚本文件的目录添加到PATH环境变量中
- 在命令行中使用绝对路径或相对路径来引用shell脚本文件
使用./test
来引用当前目录下的文件
注意修改权限保证有该文件的执行权限
11.3 显示消息
使用 echo命令在脚本中输出文本消息 — shell脚本中同用户交互的重要工具
一般使用无须使用引号划定字符串,也可用单引号或双引号划定字符串(尤其在字符串包含引号或空格时)
使用 -n 可将字符串和命令输出显示在同一行中
1 2 3 4 5 6 |
#!/bin/bash # This script displays the date and who's logged on. echo -n "The time and date are: " date echo "Let's see who's logged into the system: " who |
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
┌──(beeee㉿kali)-[~/testdir] └─$ ./test1 zsh: 权限不够: ./test1 ┌──(beeee㉿kali)-[~/testdir] └─$ ls -l 总计 4 -rw-r--r-- 1 beeee shared 157 10月31日 20:21 test1 -rw-rw-r-- 1 beeee shared 0 10月31日 12:06 testfile ┌──(beeee㉿kali)-[~/testdir] └─$ chmod u+x test1 ┌──(beeee㉿kali)-[~/testdir] └─$ ./test1 The time and date are: 2023年 10月 31日 星期二 20:25:46 CST Let's see who's logged into the system: beeee tty7 33870485-11-24 02:21 (:0) |
11.4 使用变量
环境变量
用set查看环境变量
在脚本中,可以在环境变量名之前加上$来引用环境变量
echo命令中的环境变量会在脚本运行时被替换成当前值,(使用单双引号也一样)
要在字符串中显示’$’需要在前面加入反斜线
${variable}形式引用变量方便界定$后的变量名
1 2 3 4 5 6 7 8 |
#!/bin/bash # Display user information from the system. echo "User info for userid: $USER" echo UID: $UID echo HOME: ${HOME} echo "The cost if the item is $15" echo "The cost if the item is \$15" |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
┌──(beeee㉿kali)-[~/testdir] └─$ vim test2 ┌──(beeee㉿kali)-[~/testdir] └─$ chmod u+x test2 ┌──(beeee㉿kali)-[~/testdir] └─$ ./test2 User info for userid: beeee UID: 1000 HOME: /home/beeee The cost if the item is 5 The cost if the item is $15 |
用户自定义变量
名称是由字母 数字或下划线组成的字符串,长度不超过20个字符,变量名区分大小写
使用等号为变量赋值,变量、等号和值之间不能有空格!!
引用变量使要加$,对变量赋值时不加$
shell脚本会以字符串的形式存储所有的变量值,脚本中的各个命令可以自行决定变量值的数据类型
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/bash # assigning a variable value to another variable value1=10 value2=value1 value3=$value1 echo "value1 is $value1, value2 is $value2, value3 is $value3" 输出:┌──(beeee㉿kali)-[~/testdir] └─$ ./test_value value1 is 10, value2 is value1, value3 is 10 |
命令替换
shell脚本可从shell命令输出中提取信息并将其赋给变量,有两种方法:
- 反引号
- $() 格式
命令替换会创建出子shell来运行指定命令,这是一个由运行脚本的shell所生成的一个独立的shell,因此,在子shell中运行的命令无法使用脚本中的变量
1 2 3 4 |
#!/bin/bash # copy the /usr/bin directory listing to a log file today=$(date +%y%m%d) ls /usr/bin -al > log.$today |
date +%y%m%d 会提取日期信息,用200601格式显示
该脚本会将日期值赋给变量,再将其作为文件名的一部分。 日志文件的内容是/usr/bin目录内容的列表输出,脚本在不同日期运行,会产生不同名称的新文件
运行脚本后在目录下产生了文件 log.231101
11.5 重定向输入和输出
输出重定向
最基本的重定向会将命令的输出发送至文件,使用 ‘>’ 号
1 |
command > outputfile |
要想不覆盖文件原有内容,只将输出追加到已有文件中,可用 ‘>>’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
┌──(beeee㉿kali)-[~/testdir] └─$ date > testout ┌──(beeee㉿kali)-[~/testdir] └─$ cat testout 2023年 11月 01日 星期三 20:03:22 CST ┌──(beeee㉿kali)-[~/testdir] └─$ who > testout ┌──(beeee㉿kali)-[~/testdir] └─$ cat testout beeee tty7 76305077-10-04 13:11 (:0) ┌──(beeee㉿kali)-[~/testdir] └─$ date >> testout ┌──(beeee㉿kali)-[~/testdir] └─$ cat testout beeee tty7 76305077-10-04 13:11 (:0) 2023年 11月 01日 星期三 20:03:57 CST |
输入重定向
将文件的内容重定向至命令 ‘<‘
wc
可统计数据中的文本,默认输出三个值:文本的行数,文本的单词数,文本的字节数
1 2 3 |
┌──(beeee㉿kali)-[~/testdir] └─$ wc < testout 2 11 91 |
内联输入重定向 ‘<<‘
无须使用文件进行重定向,只需在命令行中指定用于输入重定向的数据即可
必须指定一个文本标记来划分输入数据的起止。任何字符串都可以作为文本标记,但数据开始和结尾的文本标记必须一致
1 |
command << marker data marker |
1 2 3 4 5 6 7 8 |
┌──(beeee㉿beeee)-[~] └─$ wc << EOF > test string 1 > test string 2 > test string 3 > test string 4 > EOF 4 12 56 |
11.6 管道
管道连接:将命令输出直接传给另一个命令
1 |
command1 | command2 |
linux系统会同时运行这两个命令,在系统内部将二者连接起来,将第一个命令产生的输出立即传给第二个命令
管道可以串联的命令数量没有限制,可以持续地将命令输出通过管道传给其他命令来细化操作
管道最常见的用法之一是将命令产生的大量输出传送给more命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
┌──(beeee㉿beeee)-[~] └─$ ls -al | more total 236 drwx------ 22 beeee beeee 4096 Nov 8 10:40 . drwxr-xr-x 3 root root 4096 Nov 4 00:43 .. -rw------- 1 beeee beeee 310 Nov 8 10:24 .ICEauthority -rw------- 1 beeee beeee 150 Nov 8 10:24 .Xauthority -rw------- 1 beeee beeee 1716 Nov 7 23:31 .bash_history -rw-r--r-- 1 beeee beeee 220 Nov 4 00:43 .bash_logout -rw-r--r-- 1 beeee beeee 5551 Nov 4 00:43 .bashrc -rw-r--r-- 1 beeee beeee 3526 Nov 4 00:43 .bashrc.original drwxr-xr-x 11 beeee beeee 4096 Nov 6 19:46 .cache drwxr-xr-x 13 beeee beeee 4096 Nov 8 10:24 .config drwx------ 3 beeee beeee 4096 Nov 6 19:44 .dbus -rw-r--r-- 1 beeee beeee 11759 Nov 6 19:44 .face lrwxrwxrwx 1 beeee beeee 5 Nov 6 19:44 .face.icon -> .face drwx------ 3 beeee beeee 4096 Nov 8 10:24 .gnupg dr-x------ 2 beeee beeee 0 Nov 8 10:24 .gvfs drwxr-xr-x 3 beeee beeee 4096 Nov 4 00:43 .java drwxr-xr-x 3 beeee beeee 4096 Nov 6 19:44 .local drwx------ 4 beeee beeee 4096 Nov 6 19:46 .mozilla drwx------ 2 beeee beeee 4096 Nov 8 10:24 .pcsc10 --More- |
11.7 执行数学运算
expr
1 |
expr <operation> |
很多标准运算符在shell中有其他用法,需加 / 转义,使用较麻烦,不建议
使用方括号
1 |
$[operation] |
只支持整数运算
1 2 3 4 5 6 7 |
┌──(beeee㉿beeee)-[~] └─$ echo $[1 + 5 * 2] 11 ┌──(beeee㉿beeee)-[~] └─$ echo $[9 / 2] 4 |
zsh提供了完整的浮点数操作
浮点数解决方案 — bc
输入quit以退出
scale控制浮点数运算小数位数,默认值为0
在控制台中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
┌──(beeee㉿beeee)-[~] └─$ bc bc 1.07.1 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 12 * 9.4 112.8 3.155 * (3 + 5) 25.240 9 / 2 4 scale=2 9 / 2 4.50 scale=5 9 / 2 4.50000 quit |
-q 选项不显示bc的欢迎信息
bc也支持变量
1 2 3 4 5 6 7 |
┌──(beeee㉿beeee)-[~] └─$ bc -q scale=10 var1=5.5 var1 * 188 / 4.3 240.4651162790 quit |
在脚本中使用
1 |
variable=$(echo "option; expression" | bc) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#testbc #!/bin/bash var1=$(echo " scale=4; 3.44 / 5" | bc) echo The answer1 is $var1 var2=100 var3=45 var4=$(echo "scale=5; $var2 / $var3" |bc) echo The answer2 is $var4┌──(beeee㉿beeee)-[~/testdir] └─$ sudo chmod u+x testbc ┌──(beeee㉿beeee)-[~/testdir] └─$ ./testbc The answer1 is .6880 The answer2 is 2.22222 |
以上的方法适用于较短的运算,但对大量运算而言很不方便,
更好的办法是使用内联输入重定向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#testbc2 #!/bin/bash var1=10.46 var2=43.67 var3=33.2 var4=71 var5=$(bc << EOF scale = 4 a1 = ($var1 * $var2) b1 = ($var3 / $var4) a1 + b1 EOF ) echo The final answer for this mess is $var5 ┌──(beeee㉿beeee)-[~/testdir] └─$ sudo chmod u+x testbc2 ┌──(beeee㉿beeee)-[~/testdir] └─$ ./testbc2 The final answer for this mess is 457.2558 |
在这个例子中,可在bash计算器中为变量赋值,其中创建的变量仅在计算器中有效,不能在shell脚本中使用
11.8 退出脚本
shell中运行的每个命令都使用退出状态码告诉shell运行完毕
退出状态码是一个0~255的整数值,在命令结束运行时由其传给shell
可获取这个值并在脚本中使用
查看退出状态码
Linux提供了专门的变量 $? 保存最后一个已执行命令的退出状态码。
按照惯例,成功结束的命令退出状态码为0;因错误而结束的命令,其退出状态码是一个正整数;无效命令会返回退出状态码127
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
┌──(beeee㉿beeee)-[~] └─$ date Wed Nov 8 13:43:14 CST 2023 ┌──(beeee㉿beeee)-[~] └─$ echo $? 0 ┌──(beeee㉿beeee)-[~] └─$ dateee dateee: command not found ┌──(beeee㉿beeee)-[~] └─$ echo $? 127 ┌──(beeee㉿beeee)-[~] └─$ date %t date: invalid date '%t' ┌──(beeee㉿beeee)-[~] └─$ echo $? 1 |
常见错误:给命令提供无效参数的退出状态码为1
状态码 | 描述 |
---|---|
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合shell的命令 |
126 | 命令无法执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与linux信号x相关的严重错误 |
130 | 通过Ctrl+C终止的命令 |
255 | 正常范围以外的退出状态码 |
exit命令
在默认情况下,shell脚本会以脚本的最后一个命令的退出状态码退出
但exit命令允许在脚本结束时指定一个退出状态码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_ex Wed Nov 8 13:52:26 CST 2023 ┌──(beeee㉿beeee)-[~/testdir] └─$ echo $? 0 ┌──(beeee㉿beeee)-[~/testdir] └─$ vim test_ex ##!/bin/bash #date #exit 5 ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_ex Wed Nov 8 13:54:56 CST 2023 ┌──(beeee㉿beeee)-[~/testdir] └─$ echo $? 5 |
也可以使用变量作为exit的参数
但退出状态码最大为255
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
┌──(beeee㉿beeee)-[~/testdir] └─$ vim test_ex ##!/bin/bash #date #var1=10 #var2=30 #var3=$[$var1*$var2] #echo The value is $var3 #exit $var3 ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_ex Wed Nov 8 14:00:41 CST 2023 The value is 300 ┌──(beeee㉿beeee)-[~/testdir] └─$ echo $? 44 44 = 300 % 256 |
第十一章 结构化命令
12.1 if-then 、if-then-elif-then 与 if-then-else 语句
可嵌套
1 2 3 4 |
if command then commands fi |
#或
1 2 3 |
if commands;then commands fi |
if句会运行if之后的命令。 如果该命令的退出状态码为0,那么位于then部分的命令就会被执行 如果该命令的退出状态码是其他值,则then部分的命令不会被执行
fi语句用来表示if-then语句结束
1 2 3 4 5 6 7 8 9 10 11 12 |
if command1 then commands elif command2 then commands fiif commands then commands else commands fi |
then和else部分的命令都可以不止一条
示例1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#!/bin/bash #test if-then and if-then-else testuser1=beeee testuser2=NoSuchUser if grep $testuser1 /etc/passwd then echo "This is my first comand in the then block." echo "This is my second command is the then block." echo "The user $testuser1 is exist." fi echo "We are outside the if statement" echo if grep $testuser2 /etc/passwd then echo "The user is $testuser2." else echo "The user $testuser2 does not exist on this system." fi echo "We are outside the is statement." |
输出:
1 2 3 4 5 6 7 8 9 10 |
┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_if beeee:x:1000:1000:,,,:/home/beeee:/bin/bash This is my first comand in the then block. This is my second command is the then block. The user beeee is exist. We are outside the if statement The user NoSuchUser does not exist on this system. We are outside the is statement. |
示例2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/bash testuser=NoSuchUser if grep $testuser /etc/passwd then echo "The user $testuser is exist." elif ls -d /home/$testuser then echo "The user $testuser has a directory." echo "even though $testuser doesn't have an account." else echo "The user $testuser doesn't have an account." echo "abd no directory exists for the $testuser." fi echo "We are outside the if statement" |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 |
┌──(beeee㉿beeee)-[~/testdir] └─$ sudo mkdir /home/NoSuchUser ┌──(beeee㉿beeee)-[~/testdir] └─$ chmod u+x test_if2 ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_if2 /home/NoSuchUser The user NoSuchUser has a directory. even though NoSuchUser doesn't have an account. We are outside the if statement |
12.4 test命令
if-then语句无法测试命令退出状态码之外的条件,但test命令可以
1 2 3 4 |
test conditionif test condition then commands fi |
condition部分如果不写会返回非零的退出状态码 如果加入了条件 test命令会测试该条件
支持的条件有:
- 数值比较
- 字符串比较
- 文件比较
bash shell提供了另一种测试条件的方式,无须在if-then语句中写明test命令,
1 2 3 4 |
if [ condition ] then commands fi |
! 第一个方括号之后和第二个方括号之前必须留有空格
数值比较
比较 | 描述 |
---|---|
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 |
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
┌──(beeee㉿beeee)-[~/testdir] └─$ cat numeric_test #!/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 diffrent." fi |
输出:
1 2 3 4 |
┌──(beeee㉿beeee)-[~/testdir] └─$ ./numeric_test The test value 10 is greater than 5. The values are diffrent. |
注意:只支持整数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#!/bin/bash # Using numeric test evaluations value1=10 value2=11 value3=10.1 if [ $value1 -gt 5 ] then echo "The test value $value1 is greater than 5." fi if [ $value1 -eq $value3 ] then echo "$value1 and $value3 are equal." else echo "$value1 and $value3 are diffrent." fi ┌──(beeee㉿beeee)-[~/testdir] └─$ ./numeric_test The test value 10 is greater than 5. ./numeric_test: line 13: [: 10.1: integer expression expected 10 and 10.1 are diffrent. |
字符串比较
比较 | 描述 |
---|---|
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:大于号和小于号必须转义,否则会被视作重定向符,将字符串当做文件名
注意2:大于和小于顺序与sort命令所采用的不同 在比较测试中,大写字母被认为是小于小写字母的,但sort命令正好相反
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/bash #在condition中使用大于小于符号未转义 string1=soccer string2=zorbfootball if [ $string1 > $string2 ] then echo "$string1 is greater than $string2." else echo "$string1 is less than $string2." fi |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 |
┌──(beeee㉿beeee)-[~/testdir] └─$ ls numeric_test test_ex test_if test_if2 test_string_comparision testbc testbc2 ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_string_comparision soccer is greater than zorbfootball. ┌──(beeee㉿beeee)-[~/testdir] └─$ ls numeric_test test_if test_string_comparision testbc2 test_ex test_if2 testbc zorbfootball |
输出无误,但脚本把大于号解释成了输出重定向,创建了文件zorbfootball,测试条件返回了退出状态码0,if认为条件成立
应改成if [ $string1 \> $string2]
字符串是非为零
-n -z
为被定义过的字符串也被视为长度为0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#!/bin/bash string1=Soccer string2='' if [ -n $string1 ] then echo "The string '$string1' is NOT empty" else echo "The string '$string1' IS empty" fi if [ -z $string2 ] then echo "The string '$string2' IS empty" else echo "The string '$string2' is NOT empty" fi if [ -z $string3 ] then echo "The string '$string3' IS empty" else echo "The string '$string1' is NOT empty" fi |
输出:
1 2 3 4 5 |
┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_nz The string 'Soccer' is NOT empty The string '' IS empty The string '' IS empty |
文件比较
测试linux文件系统中文件和目录的状态
应用非常广泛
比较 | 描述 |
---|---|
-d file | 检查file1是否存在且为目录 |
-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旧 |
- 在将文件写入目录或准备切换到某目录前,用-d测试目录是否存在
- 在更新文件前,用 -e 测试文件是否存在
- 在尝试从文件中读取数据之前,先用 -r 测试文件是否可读
- 在删除文件前,若不想删除非空文件,用 -s 检查文件是否为空
- 在更新修改文件内容时,用 -w 测试文件是否可写
- 若想在shell脚本中运行大量程序,用 -x 检查文件是否可以运行
- 在编写软件安装脚本时,用 -nt -ot 判断文件新旧
注意:在使用-nt -ot时,不检查两文件是否都存在。若有文件不存在,那么返回信息可能存在错误
12.5 符合条件测试
用 && || 将布测试条件组合起来
- [ condition1 ] && [ condition2 ]
- [ condition1 ] || [ condition2 ]
1 2 3 4 5 6 7 |
#!/bin/bash if [ -d $HOME/testdir ] && [ -w $HOME/testdir/newfile ] then echo "The file exists and you can write to it." else echo "You cannot write to the file." fi |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
┌──(beeee㉿beeee)-[~/testdir] └─$ chmod u+x test_and ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_and You cannot write to the file. ┌──(beeee㉿beeee)-[~/testdir] └─$ touch newfile ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_and The file exists and you can write to it. |
if-then 高级特性
使用单括号
单括号允许在if语句中使用子shell
语法格式为
if (command) then commands
在这种情况下,bash shell会执行command之前,会先创建一个子shell,然后在其中执行命令。
若在if test语句中使用进程列表,退出状态码只取决于进程列表中的最后一个命令是否成功执行
使用双括号
双括号命令允许在比较过程中使用高级数学表达式
并且既能在if语句中使用,也能在脚本的普通命令中用来赋值
{{ expression }}
符号 | 描述 |
---|---|
val++ | 后增 |
val– | 后减 |
++val | 先增 |
–val | 先减 |
! | 逻辑求反 |
~ | 位求反 |
** | 幂运算 |
<< | 左位移 |
>> | 右位移 |
& | 位AND |
| | 位OR |
&& | 逻辑AND |
|| | 逻辑OR |
1 2 3 4 5 6 7 8 9 |
#!/bin/bash val1=10 if (( $vall ** 2 > 90 )) then (( val2 = $val1 ** 2 )) echo "The square of $val1 is $val2." echo "which is greater than 90." fi |
输出:
1 2 3 4 5 6 7 |
┌──(beeee㉿beeee)-[~/testdir] └─$ sudo chmod u+x test_math ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test_math The square of 10 is 100. which is greater than 90. |
使用双方括号
[[ expression ]]
可使用test命令中的标准字符串比较,还提供了模式匹配特性
模式匹配
可以定义通配符或正则表达式来匹配字符串
双等号 (==) 会将右侧的字符串视为一个模式并应用模式匹配规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#!/bin/bash if [[ $BASH_VERSION == 5.* ]] then echo "You are using the Bash Shell version 5 series." fi┌──(beeee㉿beeee)-[~/testdir] └─$ sudo chmod u+x test[[]] ┌──(beeee㉿beeee)-[~/testdir] └─$ ./test[[]] You are using the Bash Shell version 5 series. ┌──(beeee㉿beeee)-[~/testdir] └─$ echo $BASH_VERSION 5.2.15(1)-release |
注意:不是所有的shell都支持双方括号
12.7 case命令
代替 if-then-elif-then-…-else 语句
case命令会采用列表格式来检查变量的多个值
1 2 3 4 5 |
case variable in pattern1 | pattern2) commands1;; pattern3) commands2;; *) default commands;; esac |
星号会捕获所有与已知模式不匹配的值
示例:
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/bash case $USER in rich | christine) echo "Welcome $USER" echo "Please enjoy your visit.";; barbara | tim) echo "Hi there, $USER" testing) echo "Please log out when done with test." *) echo "Sorry, you are not allowed here." esac |