linux学习(十三)(shell编程(文字,变量,循环,条件,调试))

news2025/3/12 18:31:56

Shell 编程

Shell 编程,也称为 shell 脚本,是 Linux作系统不可或缺的一部分。shell 脚本实质上是系统 shell 执行的程序。虽然它可能不如 C 或 C++ 等编译语言强大,但 shell 编程对于管理级任务、自动执行重复性任务和系统监控非常有效。

大多数 Linux 发行版都带有 bash (Bourne Again Shell) 作为默认 shell,它不仅是一个出色的命令行 shell,也是一种出色的脚本语言。Shell 脚本通常是在文本编辑器中编写的,然后可以直接从 Linux 命令行运行。

bash shell 脚本的简单示例:

#!/bin/bash
# My first script
echo "Hello, World!"

'echo' 命令将其参数(在本例中为 “Hello, World!”)打印到终端。

🍳 Shell编程就像写菜谱

核心概念: 把复杂的厨房工作写成步骤清单(脚本),让电脑这个"智能厨师"自动执行


📝 基础菜谱结构(脚本示例)

#!/bin/bash
# 自动备份菜谱
echo "开始备份..."
cp -v /菜谱/*.txt /备份/  # 复制所有菜谱到备份目录
echo "备份完成!记得尝新菜哦~"

逐行解释:

  1. #!/bin/bash → 指定用Bash厨具(解释器)

  2. # 注释 → 给厨师的提醒笔记(不执行)

  3. echo → 厨房喇叭(输出信息)

  4. cp -v → 复制文件并语音播报进度


🛠️ 常用厨房工具(命令)

工具功能示例
变量食材储物罐菜名="红烧肉"
循环批量处理食材for 肉 in 猪肉 牛肉; do 焯水 $肉; done
条件判断火候控制if [ 温度 -gt 100 ]; then 调小火; fi
函数预制调料包切菜() { echo "正在切$1..." }

🌰 实用菜谱案例

1️⃣ 自动清理过期菜品(删除旧文件)

#!/bin/bash
# 删除7天前的日志
find /var/log -name "*.log" -mtime +7 -exec rm {} \;
echo "过期日志清理完毕!"
这个命令的作用是在 /var/log 目录下查找所有修改时间超过 7 天的 .log 文件,并删除它们。

具体解析:

find /var/log —— 在 /var/log 目录及其子目录中查找文件。
-name "*.log" —— 只匹配 .log 结尾的文件。
-mtime +7 —— 找出最后修改时间超过 7 天的文件(+7 表示“7 天前及更早”)。
-exec rm {} \; —— 对找到的文件执行 rm 命令,即删除这些文件({} 代表找到的文件,\; 表示 -exec 命令的结束)。
简单来说,这个命令就是清理 7 天前的日志文件,防止日志堆积占用磁盘空间。
2️⃣ 智能煮饭定时器(计划任务)

#!/bin/bash
煮饭时间=40  # 分钟

echo "⏰ 开始煮饭,设定${煮饭时间}分钟"
sleep ${煮饭时间}m && speak "饭煮好啦!" 
m 表示“分钟”,例如 sleep 30m 就会让程序暂停 30 分钟。
3️⃣ 食材库存检查(监控磁盘)

#!/bin/bash
使用率=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')

if [ $使用率 -gt 90 ]; then
   echo "⚠️ 厨房快满了!当前使用率: ${使用率}%"
else
   echo "✅ 存储空间充足: ${使用率}%"
fi
使用率=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')

df -h /:查看 / 目录的磁盘使用情况,-h 让结果以人类可读的格式显示(比如 GB、MB)。
awk 'NR==2 {print $5}':提取第二行的第五列,通常是使用率(比如 85%)。
tr -d '%':去掉 % 符号,使它变成纯数字(方便后续比较)。
if [ $使用率 -gt 90 ]; then

判断使用率是否大于 90%(如果 使用率 超过 90,就表示存储快满了)。
echo "⚠️ 厨房快满了!当前使用率: ${使用率}%"

如果磁盘使用率超过 90%,就打印警告消息 “⚠️ 厨房快满了!”(这里把磁盘比作“厨房”很有趣😆)。
else echo "✅ 存储空间充足: ${使用率}%"

如果使用率低于 90%,就打印**“✅ 存储空间充足”**,说明还有足够的磁盘空间。

🔧 厨房安全须知(最佳实践)

  1. 先试菜再上桌:用 bash -x 脚本.sh 调试

  2. 小心刀具:用 set -e 遇到错误立即停止

  3. 标记食材:变量用 ${变量} 包裹更安全

  4. 定期维护:用 shellcheck 检查脚本语法


💡 高级烹饪技巧

  • 食材组合(管道操作):

    # 找出所有图片并打包
    find . -name "*.jpg" | xargs tar -czvf photos.tar.gz
    find . -name "*.jpg"
    
    在当前目录(.)及其所有子目录中,查找扩展名为 .jpg 的文件。
    | xargs tar -czvf photos.tar.gz
    xargs 是一个构造命令参数列表并执行命令的工具。
    
    在 find . -name "*.jpg" | xargs tar -czvf photos.tar.gz 这个命令中,find 找到的 .jpg 文件名会通过 | 传递给 xargs,然后 xargs 把这些文件名作为参数拼接到 tar -czvf photos.tar.gz 后面,最终执行 tar 命令进行压缩。
    
    为什么要用 xargs?
    find 默认会把所有匹配的文件名逐行输出,但 tar 需要文件名作为参数放在同一行。
    xargs 自动把多行输出转换成一行参数列表,避免 tar 处理不了文件名的问题。
    比 find ... -exec 更高效,因为 xargs 只执行一次 tar,而 -exec 默认对每个文件执行一次(除非用 +)。
    
    |(管道符)把 find 找到的 .jpg 文件列表传递给 xargs,然后交给 tar 处理。
    tar -czvf photos.tar.gz
    c(create):创建一个新的压缩包。
    z(gzip):使用 gzip 进行压缩。
    v(verbose):显示打包过程,列出正在添加的文件。
    f photos.tar.gz:指定输出文件名 photos.tar.gz。

  • 万能锅具(Here Document):

    cat <<EOF > 菜单.txt
    今日特价:
    1. ${招牌菜}
    2. 时令蔬菜
    EOF
     
  • 秘密配方(环境变量):

    export 秘制酱料="酱油:糖=3:1"
    ./烹饪脚本.sh  # 子脚本也能使用这个配方
     

总结: Shell编程就像掌握了一套智能厨房管理系统,通过:

  • 📜 编写自动化菜谱(脚本)

  • ⚡ 批量处理食材(文件操作)

  • 🔔 设置烹饪提醒(定时任务)

  • 🛡️ 监控厨房安全(系统监控)

让你从重复劳动中解放,成为高效能的"数字大厨"! 👨🍳💻

Linux 上 Shell 编程中的文字

在 Linux 环境中,shell 脚本是系统作和应用程序开发的重要组成部分。shell 脚本的一个关键方面是使用 Literals。在计算机科学和 shell 编程中,术语“literal”是指在源代码中表示固定值的表示法。在 shell 脚本中,这些固定值可以包括字符串文本、数字文本或布尔值。在阅读和理解现有脚本或编写新脚本时,了解如何以及何时使用这些文本至关重要。下面列出了 Linux 下的一些基本 shell 脚本文字:

字符串文字:可以通过将文本括在单引号或双引号之间来定义它们。例如,'Hello, world!' 或 “Hello, world!”。

数字文本:它们表示数字序列。例如,25、100 或 1234。

布尔文本:在大多数 Linux shell 脚本中,1 表示 true,0 表示 false。

请注意您使用的文本类型,因为它会显著影响您的脚本、代码的可读性及其整体功能。

#!/bin/bash
# Example of literals in shell script
 
StringLiteral="This is a string literal"
NumericLiteral=125
echo $StringLiteral
echo $NumericLiteral

在此示例中, and 是文本 和 用于打印它们。StringLiteral NumericLiterale cho

永远记住,在 Linux 中编写 shell 脚本时,对文本的良好理解是基础。

Shell脚本中的“文字”(字面量)其实就是你直接写出来的固定值,就像我们说话时直接提到的具体内容。比如:


1️⃣ ​字符串字面量(文字)​

就是直接写出来的文字,像把一句话装进盒子里。有两种包装方式:

  • 单引号盒子 ' ':盒子里的内容会完全保持不变
    name='小明 $100'   # $符号和数字都会原样保存
  • 双引号盒子 " ":盒子里的内容可以“透气”,能识别里面的变量和特殊符号
    money=100
    name="小明有 ¥$money"  # 输出:小明有 ¥100

举个栗子🌰:

echo '今天是$HOSTNAME'  # 输出:今天是$HOSTNAME
echo "今天是$HOSTNAME"  # 输出:今天是你的电脑名称

2️⃣ ​数字字面量(文字)​

直接写数字,但要注意 ​Shell默认所有内容都是字符串,想计算需要特殊处理:

age=25          # 直接写数字
sum=$((10+15)) # 需要$(( ))才能计算

错误示范❌:

result=10+20    # 这不会计算,会被当作字符串"10+20"

3️⃣ ​布尔字面量(文字)​

Shell用 ​命令执行是否成功 表示真假:

  • 0 表示真​(True)→ 因为命令执行成功时返回0
  • 非0 表示假​(False)→ 不同的数字代表不同的错误类型

举个栗子🌰:

if grep "hello" file.txt; then
   # 如果找到"hello"(返回0),执行这里
else
   # 如果没找到(返回1),执行这里
fi

📝 ​重点总结

类型示例特点说明
字符串name="小明"单引号严格,双引号灵活
数字count=42直接写数字,计算需特殊符号
布尔成功返回0与常见编程语言相反,特别注意

小练习✍️:

# 观察以下代码的区别
num=5+3
echo $num        # 输出什么?
echo $((num))    # 输出什么?
echo $(($num))   # 又会输出什么?

通过理解这些直接写出来的“文字”,你就能更自如地控制Shell脚本的行为了!

总结

代码解析输出
echo $numnum="5+3",所以直接输出 5+35+3
echo $((num))num 里是字符串 "5+3",不能计算,会报错报错
echo $(($num))$(("5+3")),Bash 解析并计算 5+38

Linux 上 Shell 编程中的变量

在 Linux 上的 Shell 编程上下文中,变量是可以存储系统数据或用户定义数据的字符串。它是一个符号名称,分配给一定量的存储空间,该空间量可以在程序执行期间更改其值。变量在任何编程范式中都起着至关重要的作用,shell 脚本也不例外。

变量分为两大类:系统变量和用户定义的变量。系统变量由 Linux 系统本身创建和维护。示例包括 PATH、HOME 和 PWD。另一方面,用户定义的变量由用户创建和控制。

shell 脚本中的变量由 '=' (等于) 运算符定义,可以通过在变量名称前加上 '$' (美元) 符号来检索该值。

# Create a User-Defined Variable
MY_VARIABLE="Hello World"

# Print the value of the Variable
echo $MY_VARIABLE  # Output: Hello World

🏷️ Shell变量就像厨房的储物罐

核心概念: 给不同的食材(数据)贴上标签(变量名),方便随时取用和修改


🧂 变量使用基础

食材="盐"          # 贴上标签(变量赋值)
echo "请加${食材}"  # 使用时要加${}(防止混淆)
=> 请加盐
 

🥫 变量分类(储物柜类型)

变量类型特点示例查看方式
系统变量厨房自带,全大写$HOME(你的厨房位置)env 或 printenv
用户变量厨师自定义,建议小写$菜谱echo $菜谱
环境变量子厨房也能用$PATH(工具位置)export 显示
局部变量只在当前厨房有效函数内定义的变量无法直接查看

🛠️ 变量使用技巧

1️⃣ 避免标签混淆

# 错误示范(标签贴错位置)
数量=5
echo "需要$数量斤肉"  # 输出:需要5斤肉(正确)
echo "需要$数量斤肉"   # 输出:需要斤肉($数量斤被误解析)

错误示范的代码,问题出在哪里?

  • $数量 代表变量 数量,它的值是 5
  • $数量斤bash 里会被当作一个新的变量 数量斤,而不是 $数量 加上
  • 如果 数量斤 这个变量没有被定义,Bash 会解析为空字符串,导致 "需要$数量斤肉" 变成 "需要斤肉"
2️⃣ 设置只读调料瓶

readonly 秘方="酱油3勺"
秘方="醋2勺"  # 报错:秘方是只读变量
 
3️⃣ 让子厨房继承变量

export 公用调料="胡椒粉"  # 其他厨房脚本也能使用

🌰 实战菜谱示例

自动备份菜谱

#!/bin/bash
备份目录="/厨房/菜谱备份"
今日菜单=$(date +%Y%m%d).txt

echo "正在备份今日菜单..."
cp 今日菜单.txt "${备份目录}/${今日菜单}"
echo "备份完成!存放于:${备份目录}/${今日菜单}"

⚠️ 厨房安全须知

  1. 标签规则

    • 不能以数字开头:1号罐=盐 ❌ → 罐1=盐 ✅

    • 避免特殊字符:调料-油=花生油 ❌ → 调料油=花生油 ✅

  2. 赋值禁忌

    食材 = "盐"   # 等号两边不能有空格 ❌
    食材="盐"     # 正确 ✅
  3. 空值处理

    echo "缺货: ${库存:-无}"  # 库存为空时显示"无"

💡 高级调味技巧

  • 字符串切割

    完整菜名="红烧肉.jpg"
    echo ${完整菜名%.*}  # 输出:红烧肉(去掉后缀)
  • 变量计算

    鸡蛋=5
    鸡蛋=$((鸡蛋 + 3))  # 现在有8个鸡蛋
  • 命令结果存变量

    当前温度=$(sensors | grep 'CPU temp' | awk '{print $3}')
    echo "CPU温度: ${当前温度}"

总结: Shell变量就像智能厨房的标签系统:

  • 🏷️ 命名:用有意义的标签方便管理

  • 🔒 作用域:分清私房调料和公共调料

  • 🛡️ 保护:重要配方设为只读

  • 🔄 灵活使用:支持动态修改和计算

掌握这些技巧,让你的Shell脚本像米其林大厨一样高效有序! 👨🍳💻

export 的作用是让变量在子进程中也可用
✅ 变量在 export 之后仍然是当前 shell 的变量,但子进程也能访问。
export 变量在新终端不会自动生效,除非写入 ~/.bashrc~/.bash_profile
unset 可以删除 export 变量。


💡 一句话总结export 让变量变成环境变量,这样它可以在当前 shell 及所有子进程中使用,但不会影响新的终端,要让它永久生效,必须写入 ~/.bashrc~/.bash_profile。🚀

循环

shell 编程中的循环是一个基本概念,它允许根据给定条件一遍又一遍地执行某个代码块。它们对于自动执行重复性任务至关重要,从而提高编码过程的效率且不易出错。

在 Linux 中,shell 脚本通常使用三种类型的循环 - for、while 和 until。

  • forLoop 迭代项目列表并对每个项目执行作。
  • while只要控制条件保持 true,loop 就会执行命令。
  • untilloop 运行命令,直到 control condition 变为 true。

以下是 bash/shell 中的一个简单的 for 循环示例:

for i in 1 2 3
do
   echo "$i"
done

这将输出:

1
2
3

这只是 Linux 中 shell 编程中循环的表面。如果明智地使用这些结构,可以增强您的脚本并为有效的脚本编写和自动化开辟许多领域。

好的,我来用最生活化的方式解释 Shell 中的循环,就像教朋友做菜时的步骤说明:


循环就像「重复做某件事的规则」​

想象你要做以下事情:
1️⃣ ​按清单买水果 → 用 for 循环
2️⃣ ​洗碗直到洗完 → 用 while 循环
3️⃣ ​等快递直到门铃响 → 用 until 循环


1️⃣ ​**for 循环:按固定清单办事**

场景:你有一张购物清单,要依次买上面的每样东西
语法

for 物品 in 苹果 香蕉 橘子   # 清单可以是数字/文件名等
do
    echo "现在买:$物品"     # 对每个物品执行操作
done

示例

for fruit in 苹果 香蕉 橘子
do
   echo "买了 $fruit"
done

输出👇

买了 苹果  
买了 香蕉  
买了 橘子

小技巧:快速生成数字序列

for i in {1..5}         # 输出1到5
for i in $(seq 1 2 10) # 输出1 3 5 7 9(步长2)

2️⃣ ​**while 循环:只要条件成立,就一直做**

场景:洗碗时,只要还有脏碗,就继续洗
语法

while [ 条件 ]       # 条件为真(返回0)时执行
do
    echo "正在洗碗..."
    更新条件         # 必须修改条件,否则无限循环!
done

示例​(倒计时3秒):

counter=3
while [ $counter -gt 0 ]  # -gt 表示大于
do
   echo "倒计时:$counter"
   counter=$((counter-1)) # 修改条件变量
done

输出👇

倒计时:3  
倒计时:2  
倒计时:1

⚠️ 重点:条件里的方括号 [ ] 两边必须有空格!


3️⃣ ​**until 循环:一直做,直到条件成立**

场景:等快递时,每隔5分钟查一次,直到快递到了
语法

until [ 条件 ]       # 条件为假(返回非0)时执行
do
    echo "快递还没到"
    更新条件
done

示例​(从5减到0停止):

counter=5
until [ $counter -eq 0 ]  # -eq 表示等于
do
   echo "剩余次数:$counter"
   counter=$((counter-1))
done

输出👇

剩余次数:5  
剩余次数:4  
剩余次数:3  
剩余次数:2  
剩余次数:1

三种循环对比表

循环类型执行时机常用场景类比
for按已知清单逐个处理遍历文件、数字序列按购物清单买东西
while只要条件成立就执行不确定次数的重复操作洗碗直到没有脏碗
until直到条件成立才停止等待某个状态变化等快递直到门铃响

小练习✍️:
猜猜这段代码会输出什么?

for num in 3 1 4
do
   while [ $num -gt 0 ]
   do
      echo -n "$num "
      num=$((num-1))
   done
done

答案

3 2 1 1 4 3 2 1

(解释:外层for循环依次处理3→1→4,每个数字内层while循环减到0停止)

Shell 编程中的条件语句

Linux Shell 编程中的条件语句允许脚本根据条件做出决策。这些是任何编程语言不可或缺的一部分,就像 C、Python、JavaScript 等其他语言一样,Linux Shell 也提供条件语句。条件语句可以定义为 shell 脚本的组成部分,它根据给定的条件引导解释器进入正确的执行路径。

在 shell 中,用于条件语句的主要命令是 、 、 (else if) 和 。这些命令用于基于条件测试结果的流程控制,条件测试可以评估字符串变量、算术测试或流程状态的值。ifelifelse

以下是它们工作原理的简单说明:

#!/bin/sh
a=10
b=20

if [ $a -lt 20 ]
then
   echo "a is less than b"
elif [ $a -gt 20 ]
then
   echo "a is greater than b"
else
   echo "a is equal to b"
fi

在上面的脚本中,正在检查语句内的条件。如果条件为 ,则执行语句中的代码块,否则,它将移动到条件,依此类推。如果这些条件都不满足,则将执行语句中的代码块。if true if elif else

🌦️ Shell条件语句就像天气决策指南

核心概念: 根据不同的天气条件(判断条件),决定今天要做什么(执行不同代码块)


📝 基础天气预报结构

#!/bin/bash
温度=25

if [ $温度 -lt 10 ]; then
   echo "❄️ 穿羽绒服!"
elif [ $温度 -lt 20 ]; then
   echo "🍂 穿外套吧"
else
   echo "☀️ 短袖出门~"
fi
 

🌈 天气判断要素解析

条件符号含义示例生活类比
-lt小于(<)[ $温度 -lt 30 ]温度低于30度
-gt大于(>)[ $电量 -gt 20 ]电量高于20%
-eq等于(==)[ $星期 -eq 1 ]周一
-ne不等于(!=)[ $天气 != "雨" ]不是雨天
-le小于等于(<=)[ $年龄 -le 18 ]未成年人
-ge大于等于(>=)[ $身高 -ge 120 ]身高120cm以上

🌰 真实生活场景案例

1️⃣ 文件备份检查

if [ -f "/data/备份.zip" ]; then
   echo "✅ 备份存在"
else
   echo "⚠️ 警告:未找到备份文件!"
   exit 1
fi
2️⃣ 用户输入判断

read -p "今天要带伞吗?(y/n): " 选择
if [ "$选择" = "y" ]; then
   echo "🌂 记得放包里"
elif [ "$选择" = "n" ]; then
   echo "☀️ 享受晴天吧"
else
   echo "输入错误,请重新选择"
fi
3️⃣ 多条件组合

if [ $时间 -gt 6 -a $时间 -lt 18 ]; then
   echo "现在是白天"
elif [ $时间 -lt 6 -o $时间 -ge 18 ]; then
   echo "现在是夜晚"
fi

⚠️ 天气预测注意事项

  1. 空格敏感 → 方括号两边必须有空格
    ❌错误:[$温度<25]
    ✅正确:[ $温度 -lt 25 ]

  2. 变量防护 → 用双引号包裹变量防止空值
    ❌危险:[ $文件名 == "test" ]
    ✅安全:[ "$文件名" == "test" ]

  3. 逻辑运算符

    • -a → 且(and)

    • -o → 或(or)


💡 高级天气预测技巧

  • 文件测试

    if [ -d "/data" ]; then  # 检查是否是目录
       echo "找到数据仓库"
    fi
  • 字符串比较

    if [ "$OSTYPE" = "linux-gnu" ]; then
       echo "Linux系统"
    fi

$OSTYPE 是一个系统变量

OSTYPE 变量存储了当前操作系统的类型,比如:
在 Linux 上,echo $OSTYPE 通常输出 linux-gnu
在 macOS 上,echo $OSTYPE 通常输出 darwin
在 Windows(WSL)上,可能输出 linux-gnu
    • 数学运算

      if (( 温度 > 30 )); then  # 双括号支持数学表达式
         echo "高温预警!"
      fi

    总结: Shell条件语句就像智能天气预报系统,通过:

    • 🌧️ 基础判断 → 单条件决策

    • ⛅ 多级判断 → 处理复杂天气变化

    • 🌈 组合条件 → 应对特殊天气组合
      让你的脚本具备智能决策能力!

    在 Linux 下进行 Shell 编程调试

    Linux 是一个强大而灵活的作系统,许多开发人员和系统管理员都喜欢它的多功能性和强大功能。特别是,Linux 中的 shell 编程允许您高效地自动执行任务和管理系统。但是,鉴于 shell 脚本的复杂性,调试是处理错误和提高代码性能的一项基本技能。

    在 shell 脚本中遇到问题时,您可以在 Linux 环境中使用多种调试工具。这些有助于检测、跟踪和修复 shell 脚本中的错误或错误。其中一些调试工具包括 bash shell 的 (or ) 选项,这些选项允许执行跟踪。其他工具(如 , command),甚至利用外部调试工具(如 )也可能非常有效。-x -v trap set shellcheck

    考虑使用 -x 选项打开 shell 脚本以进行执行跟踪,如下所示:

    #!/bin/bash -x

    或者,您可以直接从命令行在调试模式下运行脚本。

    bash -x script.sh

    这些调试工具和选项可以极大地帮助您使脚本更加防错和高效。

    我来用生活中「修理东西」的场景,帮你理解 Shell 脚本调试的套路:


    调试就像修漏水的水管

    想象你家的水管漏水,但不知道哪里破了。你会:
    1️⃣ ​看水从哪流出来 → 用 -x 选项看脚本执行流程
    2️⃣ ​分段检查水管 → 用 set -x 和 set +x 局部调试
    3️⃣ ​用检测仪找裂缝 → 用 shellcheck 工具提前发现隐患


    1️⃣ ​​「全程监控」模式:bash -x 或 #!/bin/bash -x

    作用:像摄像头一样记录脚本每一步的执行过程
    示例:调试一个打印数字的脚本

    #!/bin/bash -x  # 关键在这里!
    for i in 1 2 3
    do
      echo "Number: $i"
    done

    输出👇(带 + 的行是调试信息)

    + for i in 1 2 3
    + echo 'Number: 1'
    Number: 1
    + for i in 1 2 3
    + echo 'Number: 2'
    Number: 2
    + for i in 1 2 3
    + echo 'Number: 3'
    Number: 3

    适用场景:快速定位脚本卡在哪里,观察变量值变化


    2️⃣ ​​「局部放大镜」调试:set -x 和 set +x

    作用:只检查脚本的某一段代码,避免信息过多
    示例:只监控循环部分

    #!/bin/bash
    echo "开始执行"
    set -x  # 从这里开始记录
    for i in {1..2}
    do
      echo "第 $i 次循环"
    done
    set +x  # 到这里停止记录
    echo "执行结束"

    输出👇

    开始执行
    + for i in '{1..2}'
    + echo '第 1 次循环'
    第 1 次循环
    + for i in '{1..2}'
    + echo '第 2 次循环'
    第 2 次循环
    + set +x
    执行结束

    适用场景:长脚本中重点排查某段代码


    3️⃣ ​​「智能安检仪」:shellcheck 工具

    作用:像机场安检机,提前发现脚本中的隐患
    安装sudo apt install shellcheck(Debian/Ubuntu)
    使用

    shellcheck 你的脚本.sh

    示例:检查一个未引用的变量

    # 问题脚本 test.sh
    name=Kk
    if [ $name == "Kk" ]  # 这里$name没加引号!
    then
      echo "YES"
    fi

    运行 shellcheck test.sh 会提示:

    Line 2: if [ $name == "Kk" ]  
             ^-- SC2077: 建议给$name加双引号,避免空格导致错误

    优点:提前发现语法错误、不安全代码


    4️⃣ ​​「紧急刹车」调试:trap 命令

    作用:在脚本出错时自动触发调试(类似汽车碰撞时弹气囊)
    示例:任何命令失败时打印错误行

    #!/bin/bash
    trap 'echo "出错啦!在行号: $LINENO"' ERR  # 捕获错误信号
    echo "第一步正常"
    ls 不存在的文件    # 这里会报错
    echo "第二步正常"  # 不会执行到这里

    输出👇

    第一步正常
    ls: 无法访问'不存在的文件': 没有那个文件或目录
    出错啦!在行号: 4

    适用场景:捕捉脚本崩溃前的状态


    5️⃣ ​​「人工检查」技巧:echo 打印变量

    作用:像用便签纸标记重要位置,手动确认变量值
    示例:检查循环变量

    for user in "Tom" "Jerry"
    do
      echo "调试点:当前用户是 $user" >&2  # >&2 表示输出到错误流
      # ...其他代码...
    done

    输出👇

    调试点:当前用户是 Tom
    调试点:当前用户是 Jerry

    优点:简单粗暴有效,适合快速测试


    调试工具对比表

    方法适用阶段优点类比
    bash -x运行时调试全局跟踪执行流程水管全段摄像头
    set -x运行时调试局部精准检查手电筒照特定区域
    shellcheck写代码时提前预防错误施工前的设计检查
    trap运行时错误处理捕捉崩溃瞬间状态汽车黑匣子
    echo任何情况灵活直观贴便签做标记

    调试小贴士💡:

    1. 遇到无限循环时,按 Ctrl + C 强制终止
    2. 变量赋值后立即用 echo 确认值是否正确
    3. 复杂脚本用 # 注释掉部分代码,分段测试
    4. 错误信息别怕,先看行号,再检查附近代码

    练习:写一个错误脚本(比如计算 1+2 但结果错误),用以上方法调试并修复它!

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313886.html

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

    相关文章

    wireshark 如何关闭混杂模式 wireshark操作

    Fiddler和Wireshark都是进行抓包的工具&#xff1a;所谓抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作&#xff0c;也用来检查网络安全。抓包也经常被用来进行数据截取等。黑客常常会用抓包软件获取你非加密的上网数据&#xff0c;然后通过分析&#…

    ChatGPT4.5详细介绍和API调用详细教程

    OpenAI在2月27日发布GPT-4.5的研究预览版——这是迄今为止OpenAI最强大、最出色的聊天模型。GPT-4.5在扩大预训练和微调规模方面迈出了重要的一步。通过扩大无监督学习的规模&#xff0c;GPT-4.5提升了识别内容中的模式、建立内容关联和生成对于内容的见解的能力&#xff0c;但…

    Unity DOTS从入门到精通之 自定义Authoring类

    文章目录 前言安装 DOTS 包什么是Authoring1. 实体组件2. Authoring类 前言 DOTS&#xff08;面向数据的技术堆栈&#xff09;是一套由 Unity 提供支持的技术&#xff0c;用于提供高性能游戏开发解决方案&#xff0c;特别适合需要处理大量数据的游戏&#xff0c;例如大型开放世…

    一键换肤的Qt-Advanced-Stylesheets

    项目简介 能在软件运行时对 CSS 样式表主题&#xff08;包括 SVG 资源和 SVG 图标&#xff09;进行实时颜色切换的Qt项目。 项目预览&#xff1a; 项目地址 地址&#xff1a;Qt-Advanced-Stylesheets 本地编译环境 Win11 家庭中文版 Qt5.15.2 (MSVC2019) Qt Creator1…

    golang 静态库 Undefined symbol: __mingw_vfprintf

    正常用golang编译一个静态库给 其他语言 调用&#xff0c;编译时报错 Error: Undefined symbol: __mingw_vfprintf 很是奇怪&#xff0c;之前用用golang写静态库成功过&#xff0c;编译也没问题&#xff0c;结果却是截然不同。 试了很多次&#xff0c;发现唯一的差别就是在 …

    Linux 网络:skb 数据管理

    文章目录 1. 前言2. skb 数据管理2.1 初始化2.2 数据的插入2.2.1 在头部插入数据2.2.2 在尾部插入数据 2.2 数据的移除 3. 小结 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. skb 数据管理 数…

    wireguard搭配udp2raw部署内网

    前言 上一篇写了使用 wireguard 可以非常轻松的进行组网部署&#xff0c;但是如果服务器厂商屏蔽了 udp 端口&#xff0c;那就没法了 针对 udp 被服务器厂商屏蔽的情况&#xff0c;需要使用一款 udp2raw 或 socat 类似的工具&#xff0c;来将 udp 打包成 tcp 进行通信 这里以…

    Qwen/QwQ-32B 基础模型上构建agent实现ppt自动生成

    关心Qwen/QwQ-32B 性能测试结果可以参考下 https://zhuanlan.zhihu.com/p/28600079208https://zhuanlan.zhihu.com/p/28600079208 官方宣传上是该模型性能比肩满血版 DeepSeek-R1&#xff08;671B&#xff09;&#xff01; 我们实现一个 使用Qwen/QwQ-32B 自动生成 PowerPoi…

    PostgreSQL17(最新版)安装部署

    PostgreSQL 17已与2024年9月26日正式发布&#xff01;&#xff01;&#xff01; 一、Postgres概述 官网地址&#xff1a;PostgreSQL: The world’s most advanced open source database Postgres作为最先进的开源数据库&#xff08; the latest version of the world’s most…

    【AI大模型智能应用】Deepseek生成测试用例

    在软件开发过程中&#xff0c;测试用例的设计和编写是确保软件质量的关键。 然而&#xff0c;软件系统的复杂性不断增加&#xff0c;手动编写测试用例的工作量变得异常庞大&#xff0c;且容易出错。 DeepSeek基于人工智能和机器学习&#xff0c;它能够依据软件的需求和设计文…

    【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台

    【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台 文章目录 准备工作连接设备RTMP概念ENCSHV2推流地址设置大疆Pocket 3直播设置总结 老铁们好&#xff01; 很久没写软文了&#xff0c;今天给大家带了一个干货&#xff0c;如上图&#xff0c;大疆Pocket 3加ENC编…

    机器人交互系统 部署构建

    环境要求 Ubuntu 20.04 或更高版本ROS Noetic 或兼容版本Python 3.8 安装步骤 1. 安装ROS环境&#xff08;如未安装&#xff09; sudo apt update sudo apt install ros-noetic-desktop-full source /opt/ros/noetic/setup.bash2. 创建工作空间并克隆代码 mkdir -p ~/code…

    创建模式-工厂方法模式(Factory Method Pattern)

    江城子乙卯正月二十日夜记梦 目的动机简单工厂示例代码 目的 定义一个创建对象的接口&#xff0c;该接口的子类具体负责创建具体的对象。工厂方法模式将对象的实例化延迟到子类。简单工厂是直接在创建方法中负责所有的产品的生成&#xff0c;造成该方法臃肿&#xff0c;并且当…

    【eNSP实战】交换机配置端口隔离

    交换机端口隔离可以实现在同一个VLAN内对端口进行逻辑隔离&#xff0c;端口隔离分为L2层隔离和L3层隔离&#xff0c;这里只进行L2层隔离演示。 拓扑图 路由器AR1配置GE 0/0/1配置IP&#xff0c;其余PC主机各自配置IP和网关。 现将PC1到PC4四个主机全部进行L2层隔离&#xff0c…

    人脸识别之数据集中 PI20 和 CFMT 之间关联的模型预测贝叶斯(Python+论文代码实现)

    代码文件&#xff08;联系作者点击这里末尾&#xff09; 代码文件描述如下&#xff1a; subjective_objective.ipynb和&#xff1a;这分别是实际的笔记本和 Web 浏览器友好的只读版本。此笔记本读取数据&#xff0c;执行一些预处理&#xff0c;并包含论文中使用的模型规范。它…

    静态时序分析:无法满足的生成时钟(TIM-255警告、UITE-461或PTE-075错误)

    相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在阅读本文前&#xff0c;强烈建议首先阅读介绍生成时钟的文章&#xff0c;尤其是其中关于时钟极性和反相的相关内容。 静态时序分析&#xff1a;SDC约束命令cr…

    VSTO(C#)Excel开发2:Excel对象模型和基本操作

    初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

    途游游戏25届AI算法岗内推

    熟悉常用的编程语言&#xff0c;如Python、R等&#xff0c;具有良好的编码和调试能力&#xff1b;对常用的机器学习算法和深度学习框架&#xff08;如TensorFlow、PyTorch等&#xff09;有深入理解&#xff0c;对大型语言模型有一定了解&#xff0c;具备模型部署和微调的实践经…

    【数据分析大屏】基于Django+Vue汽车销售数据分析可视化大屏(完整系统源码+数据库+开发笔记+详细部署教程+虚拟机分布式启动教程)✅

    目录 一、项目背景 二、项目创新点 三、项目功能 四、开发技术介绍 五、项目功能展示 六、权威视频链接 一、项目背景 汽车行业数字化转型加速&#xff0c;销售数据多维分析需求激增。本项目针对传统报表系统交互性弱、实时性差等痛点&#xff0c;基于DjangoVue架构构建…

    OpenCV应用:三种图像风格化案例

    OpenCV 本身主要用于计算机视觉任务&#xff0c;例如图像处理、边缘检测、物体识别等&#xff0c;虽然它并不直接提供像 Photoshop 或其他艺术设计软件那样的 "风格化" 功能&#xff0c;但你可以通过一些图像处理技术在 OpenCV 中实现不同风格化效果。 1. 卡通化效果…