一、Shell 脚本编写逻辑与调试方法

1.1 脚本怎么写(思路):

① 根据需求,测试你的命令能不能实现,语法对不对,注意路径的表达方式
② 写在脚本中,变量化转换,在命令测试通过后,将硬编码的路径、参数等转换为变量(如位置变量 `$1` 或自定义变量),以提升脚本的通用性与可维护性。
③ Debug 调试:利用 `bash -x` 命令执行脚本,通过观察变量替换后的实际执行命令来排查语法错误(如路径符号转义、引号匹配等)。

1.2  变量定义与使用策略

按需定义变量:反对一次性定义所有变量,建议在编写过程中“用到什么写什么”,避免因变量过多导致逻辑混乱。

路径变量处理:当路径中包含特殊符号(如 `/`)导致变量引用出错时,建议将路径赋值给中间变量,再进行后续操作。

二、条件测试与逻辑运算符

2.1 测试表达式语法

两种测试方式:`test` 命令和 `[]` 符号两种条件测试写法,强调 `[]` 内部必须留有空格,否则会导致报错。

中括号的语义区分:在 Shell 脚本中,中括号 `[ ]` 用于表示条件判断,而非正则表达式中的任意字符匹配。

文件属性判断: `-e`(存在)、`-f`(普通文件)、`-d`(目录)、`-r`(读权限)等常用文件测试符。

2.2 数值与字符串比较

比较操作符:区分字符串比较(`=`、`!=`)和数值比较(`-eq`、`-ne`、`-gt`、`-lt`),在 `[]` 中数值比较必须使用字母操作符。

算术运算支持:`(())` 双括号结构,该结构支持算术运算(如 `((99+1==100))`),且内部可直接使用数学符号(`>`、`<`)。

2.3 逻辑运算符应用

短路逻辑:讲解了 `&&`(与)和 `||`(或)的短路特性。`&&` 表示前一条命令成功(返回 0)才执行后一条;`||` 表示前一条命令失败(非 0)才执行后一条。

返回值判断:强调条件判断的本质是检查上一条命令的返回值(`$?`),0 表示成功/真,非 0 表示失败/假。

2.4 逻辑操作符的差异化使用

逻辑与(AND)的两种写法:`-a` 和 `&&` 均表示逻辑与,但 `-a` 通常用于单中括号 `[ ]` 内部连接条件,而 `&&` 用于连接两个独立的命令或双中括号 `[[ ]]` 内部。

逻辑或(OR)与逻辑非(NOT):`||` 表示逻辑或,`!` 表示逻辑非。在单中括号中使用 `-o` 表示逻辑或,但推荐使用双中括号 `[[ ]]` 来支持更直观的 `&&` 和 `||` 操作。

2.5 补充 Shell 脚本编写逻辑与技巧

2.5.1 输出重定向与静默执行

混合输出重定向:使用 `command > /dev/null 2>&1` 将标准输出和标准错误输出均重定向到“回收站”,避免脚本执行过程中的信息干扰。

逻辑与符号应用:利用 `&&` 连接命令,仅在第一条命令执行成功(返回值为 0)时才执行后续命令,保证流程的连贯性。

2.5.2 条件判断与流程控制

返回值判断逻辑:利用 `$?` 获取上一条命令的退出状态码,结合 `if` 语句判断命令是否执行成功(`$?` 等于 0 为成功)。

双分支与退出机制:脚本采用 `if-then-else` 结构,在成功时输出提示并正常退出(`exit 0`),在失败时输出错误信息并异常退出(`exit 1` 或 `exit 2`)。

2.5.3 多分支条件判断(else if)

语法规范:演示了 `if...then...elif...then...else...fi` 的完整结构,强调 `elif` 和 `else` 后无需再写 `then`,但 `if` 和 `elif` 后必须接条件。

应用场景:适用于处理多个并列的、互斥的条件分支,如菜单选择或分数区间划分。

三、Case 语句的语法与应用

3.1 基础语法与逻辑结构


case 语句

case 变量值 in
模式 1)
命令序列 1
;;
模式 2)
命令序列 2
;;
……
* )
默认命令序列
esac

标准格式定义:`case` 语句以 `case` 开头,后接变量名和 `in`,每个分支以 `)` 结束,执行指令后以 `;;` 分隔,最后以 `esac` 反向拼写结束整个语句块。

区间匹配逻辑:演示了如何利用 `case` 进行区间判断(如分数评级),通过 `[85-100]` 等表达式匹配变量值,并利用 `*` 通配符处理未匹配的默认情况。

变量赋值与运算:展示了在 `case` 分支中进行变量赋值(如 `let sum=$sum+200`)的方法,实现了根据用户选择动态累加消费金额的功能。

2. 实战案例:服务管理与游戏逻辑

服务控制脚本:编写了防火墙管理脚本,通过 `case` 匹配 `$1` 位置参数(如 `start`、`stop`),调用 `systemctl` 命令实现对服务的启停控制。

石头剪刀布游戏:利用 `case` 确定用户输入(0/1/2),结合 `if` 嵌套判断随机数,实现了“石头剪刀布”的胜负逻辑判定。

# 人为判断:0(石头) 赢 1(剪刀) 输 2(布) ,  1 赢 2 输 0 , 2 赢 0 输 1

RDOM=$(($RANDOM % 3))
read -p 与用户交互 "请输入一个数字,和系统猜拳,(0代表石头 1代表剪刀 2代表布)"  NUMBER

case $NUMBER in 
0)
   if [ $RDOM -eq 1 ]
     then 
       echo "你赢了"
   elif [ $RDOM -eq $NUMBER ]
     then  
       echo "平"
   else  
     echo "你输了"
   fi
;;
1)
   if [ $RDOM -eq 2 ]
     then 
       echo "你赢了"
   elif [ $RDOM -eq $NUMBER ]
     then  
       echo "平"
   else  
     echo "你输了"
   fi
;;
2)
   if [ $RDOM -eq 0 ]
     then 
       echo "你赢了"
   elif [ $RDOM -eq $NUMBER ]
     then  
       echo "平"
   else  
     echo "你输了"
   fi
;;
*)
 echo "输入有误"
esac

商品共花费统计脚本

#!/bin/bash
sum=0
read -p "当前商店有以下商品,请选购:
1、鼠标 200
2、键盘 10
3、笔记本电脑 210: " SCORE

case $SCORE in
1)
  let sum=$sum+200
;;
2)
  let sum=$sum+10
;;
3)
  let sum=$sum+210
;;
esac
echo "一共花费${sum}元"

总结

条件测试与条件判断

条件判断:
test -e /opt/1.txt 
[ -e /opt/1.txt ] 
以上的条件判断是否成立,是通过返回值是否为 0 来完成的。

条件判断常用的操作符:
-e 是否存在
-f 目标是普通文件
-d 目标是目录
-L 目标是链接
-r 目标拥有"读"权限
-w 目标拥有"写"权限
-x 目标拥有"执行"权限

#&&/-a 和 ||/-o 的用法
&& 表示:左边的指令返回值为0后,才会执行右边的指令
|| 表示:左边的指令不输出(返回值为!0),才会输出右边的指令
[root@localhost opt]# [ -f /opt/1.txt ] && echo true || echo false
false

用于比较的符号:
常用的操作符:
-eq:等于                ==
-ne:不等于                !=
-gt:大于                \>
-lt:小于                \<
-le:小于等于             <=
-ge:大于等于             >=


a=19
[ $a -gt 10 ] && [ $a -lt 20 ]

多分支:
if 今天吃米饭类
  then 
    echo "去吃米饭"
  else 
    echo "吃其他的"
fi 

假设,我还有其他的选则性:米饭、面条、烤鱼、馒头

if 今天吃米饭类 
  then
    echo 
  elif 吃面条
   then 
    echo 
  elif 吃烤鱼
   then  
    echo 
  else
   echo "吃馒头"
fi 

更多推荐