正文
进阶内容
1. if-then 语句
在其他编程语言中,if 语句之后的对象是一个等式,这个等式的求值结果为 TRUE 或 FALSE。但 bash shell 的 if 句并不这么做。
bash shell 的 if 语句会运行 if 后面的那个命令。如果该命令的退出状态码是 0,位于 then 部分的命令就会被执行。如果该命令的退出码是其他值,then 部分的命令就不会被执行,bash shell 会继续执行脚本中的下一个命令。fi 语句用来表示 if-then 语句到此结束。
#!/bin/bash # Program: # testing the if statement # History: # 2021-12-17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path if pwd then echo It worked fi exit 0
2. if-then-else 语句
在 if-then 语句中,不管命令是否成功执行,你都只有一种选择。如果命令返回一个非零退出状态码,bash shell 会继续执行脚本中的下一条命令。在这种情况下,如果能够执行另一组命令就好了。这正是 if-then-else 语句的作用。
#!/bin/bash # Program: # testting the else section # History: # 2021-12-17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path testuser=NoSuchUser if grep ${testuser} /etc/passwd then echo "The bash files for user ${testuser} are:" ls -a /home/${testuser}/.b* echo else echo "The user ${testuser} does not exist on this system." echo fi exit 0
3. 嵌套 elif
在 elif 语句中,紧跟其后的 else 语句属于 elif 代码块。他们并不是之前的 if-then 代码块。
#!/bin/bash # Program: # testing netsed ifs # History: # 2021-12-17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path 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 exists on this system." echo "However, ${testuser} has a directory." fi exit 0
4. test 命令
test 命令提供了在 if-then 语句中测试不同条件的途径。如果 test 命令中列出的条件成立,test 命令就会退出并返回退出状态码 0。这样 if-then 语句就与其他变成语言中的 if-then 语句以类似的方式工作了。如果条件不成立,test 命令就会退出并返回非零的退出状态码。这使得 if-then 语句不会再被执行。
但,这里重点讲的是 bash shell 提供的另一种条件测试方法,无需在 if-then 语句中声明 test 命令。
if [ condition ] then commands fi
方括号定义了测试条件。注意第一个方括号和第二个方括号之前必须加上一个空格,否则会报错
4.1 数值比较
- n1 -eq n2
检查 n1 是否与 n2 相等(equal) - n1 -ge n2
检查 n1 是否大于或等于 n2(greater than or equal) - n1 -gt n2
检查 n1 是否大于 n2(greater than) - n1 -le n2
检查 n1 是否小于或等于 n2(less than or equal) - n1 -lt n2
检查 n1 是否小于 n2(less than) - n1 -ne n2
检查 n1 是否不等于 n2(not equal)
(知道英文的全称之后,其实很好记简称了。)
#!/bin/bash # Program: # Using numeric test evaluations # History: # 2021/12/17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path 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 "Value1 equal to value2" else echo "The values are different" fi exit 0
4.2 字符串比较
- str1 = str2
检查 str1 是否等于 str2 - str1 != str2
检查 str1 是否不等于 str2 - str1 < str2
检查 str1 是否比 str2 小 - str1 > str2
检查 str1 是否比 str2 大 - -n str1
(!!!常用)检查 str1 是否非空串 - -z str1
(!!!常用)检查 str1 是否空串
#!/bin/bash # Program: # testing string length # History: # 2021-12-17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path 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 exit 0
4.3 文件比较
这里只捡几个常用的说
- -d file
检查 file 是否存在并是一个目录 - -e file
检查 file 是否存在 - -f file
检查 file 是否存在并是一个文件 - -O file
检查 file 是否存在并属当前用户所有
#!/bin/bash # Program: # Check if either a directory or file exists # History: # 2021/12/17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path item_name=${HOME}/sentinel echo echo "The item being checked: ${item_name}" echo if [ -e ${item_name} ] then echo "The item, ${item_name}, does exist" echo "But is it a file?" echo if [ -f ${item_name} ] then echo "Yes,${item_name} is a file" else echo "The item, ${item_name} is not a file." fi else echo "The item, ${item_name}, does not exist." echo "Nothing to update" fi exit 0
#!/bin/bash # Program: # check file ownership # History: # 2021/12/17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path if [ -O /etc/passwd ] then echo "You are the owner of the /etc/passwd file" else echo "Sorry, You are not the owner of the /etc/passwd file" fi exit 0
PS:尤其【-O file】命令特别重要,很多时候在 Linux 服务器上都是不建议用 root 用户执行脚本的,这时如果在脚本开始的时候使用这个命令,就可以避免 root 用户执行脚本的问题。
5. if-then 的高级特性
bash shell 提供了两项可在 if-then 语句中使用的高级特性:
- 用于数学表达式的双括号
- 用于高级字符串处理功能的双方括号
5.1 双括号
双括号命令允许你在比较过程中使用高级数学表达式,命令格式如下,
(( expression ))
expression 可以是任意的数学赋值或比较表达式。
#!/bin/bash # Program: # using double parenthesis # History: # 2021/12/17 junfenghe.cloud@qq.com version:0.0.1 val1=10 if (( ${val1} ** 2 > 90 )) # ** 表示平方 then (( val2 = ${val1} ** 2 )) echo "The square of ${val1} is ${val2}" fi exit 0
5.2 双方括号
双方括号提供了针对字符串比较的高级特性——模式匹配,命令格式如下,
[[ expression ]]
#!/bin/bash # Program: # using pattern matching # History: # 2021/12/17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path if [[ ${USER} == r* ]] then echo "hello ${USER}" else echo "Sorry, I do not know you" fi exit 0
7. case 命令
case 命令会将指定的变量于不同模式进行比较。如果变量和模式是匹配的,那么 shell 会执行为该模式指定的命令。可以通过竖线操作符在一行中分隔出多个模式。星号会捕获所有与已知模式不匹配的值。命令格式如下(注意到那两个双引号了吧,这是规范,不要少写了),
case variable in pattern1 | pattern2) commands1;; pattern3) commands2;; *) default commands;; esac
#!/bin/bash # Program: # using the case command # History: # 2021/12/17 junfenghe.cloud@qq.com version:0.0.1 path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export path 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 exit 0
所有命令都是一个一个单词手敲出来的,在买的服务器上练习,练习了一遍,工作上的脚本也优化了一遍(感觉能用的就都用上了),这边再输出一遍,算是多巩固了两次。