linux学习(十三)(shell编程(文字,变量,循环,条件,调试))
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 "备份完成!记得尝新菜哦~"
逐行解释:
-
#!/bin/bash→ 指定用Bash厨具(解释器) -
# 注释→ 给厨师的提醒笔记(不执行) -
echo→ 厨房喇叭(输出信息) -
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 ]; thenecho "⚠️ 厨房快满了!当前使用率: ${使用率}%"
elseecho "✅ 存储空间充足: ${使用率}%"
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%,就打印**“✅ 存储空间充足”**,说明还有足够的磁盘空间。
🔧 厨房安全须知(最佳实践)
-
先试菜再上桌:用
bash -x 脚本.sh调试 -
小心刀具:用
set -e遇到错误立即停止 -
标记食材:变量用
${变量}包裹更安全 -
定期维护:用
shellcheck检查脚本语法
💡 高级烹饪技巧
-
食材组合(管道操作):
# 找出所有图片并打包 find . -name "*.jpg" | xargs tar -czvf photos.tar.gzfind . -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 scriptStringLiteral="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 $num | num="5+3",所以直接输出 5+3 | 5+3 |
echo $((num)) | num 里是字符串 "5+3",不能计算,会报错 | 报错 |
echo $(($num)) | $(("5+3")),Bash 解析并计算 5+3 | 8 |
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).txtecho "正在备份今日菜单..."
cp 今日菜单.txt "${备份目录}/${今日菜单}"
echo "备份完成!存放于:${备份目录}/${今日菜单}"
⚠️ 厨房安全须知
-
标签规则:
-
不能以数字开头:
1号罐=盐❌ →罐1=盐✅ -
避免特殊字符:
调料-油=花生油❌ →调料油=花生油✅
-
-
赋值禁忌:
食材 = "盐" # 等号两边不能有空格 ❌ 食材="盐" # 正确 ✅ -
空值处理:
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
doecho "$i"
done
这将输出:
1
2
3
这只是 Linux 中 shell 编程中循环的表面。如果明智地使用这些结构,可以增强您的脚本并为有效的脚本编写和自动化开辟许多领域。
好的,我来用最生活化的方式解释 Shell 中的循环,就像教朋友做菜时的步骤说明:
循环就像「重复做某件事的规则」
想象你要做以下事情:
1️⃣ 按清单买水果 → 用 for 循环
2️⃣ 洗碗直到洗完 → 用 while 循环
3️⃣ 等快递直到门铃响 → 用 until 循环
1️⃣ **for 循环:按固定清单办事**
场景:你有一张购物清单,要依次买上面的每样东西
语法:
for 物品 in 苹果 香蕉 橘子 # 清单可以是数字/文件名等
doecho "现在买:$物品" # 对每个物品执行操作
done
示例:
for fruit in 苹果 香蕉 橘子
doecho "买了 $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)时执行
doecho "正在洗碗..."更新条件 # 必须修改条件,否则无限循环!
done
示例(倒计时3秒):
counter=3
while [ $counter -gt 0 ] # -gt 表示大于
doecho "倒计时:$counter"counter=$((counter-1)) # 修改条件变量
done
输出👇
倒计时:3
倒计时:2
倒计时:1
⚠️ 重点:条件里的方括号 [ ] 两边必须有空格!
3️⃣ **until 循环:一直做,直到条件成立**
场景:等快递时,每隔5分钟查一次,直到快递到了
语法:
until [ 条件 ] # 条件为假(返回非0)时执行
doecho "快递还没到"更新条件
done
示例(从5减到0停止):
counter=5
until [ $counter -eq 0 ] # -eq 表示等于
doecho "剩余次数:$counter"counter=$((counter-1))
done
输出👇
剩余次数:5
剩余次数:4
剩余次数:3
剩余次数:2
剩余次数:1
三种循环对比表
| 循环类型 | 执行时机 | 常用场景 | 类比 |
|---|---|---|---|
for | 按已知清单逐个处理 | 遍历文件、数字序列 | 按购物清单买东西 |
while | 只要条件成立就执行 | 不确定次数的重复操作 | 洗碗直到没有脏碗 |
until | 直到条件成立才停止 | 等待某个状态变化 | 等快递直到门铃响 |
小练习✍️:
猜猜这段代码会输出什么?
for num in 3 1 4
dowhile [ $num -gt 0 ]doecho -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=20if [ $a -lt 20 ]
thenecho "a is less than b"
elif [ $a -gt 20 ]
thenecho "a is greater than b"
elseecho "a is equal to b"
fi
在上面的脚本中,正在检查语句内的条件。如果条件为 ,则执行语句中的代码块,否则,它将移动到条件,依此类推。如果这些条件都不满足,则将执行语句中的代码块。if true if elif else
🌦️ Shell条件语句就像天气决策指南
核心概念: 根据不同的天气条件(判断条件),决定今天要做什么(执行不同代码块)
📝 基础天气预报结构
#!/bin/bash
温度=25if [ $温度 -lt 10 ]; thenecho "❄️ 穿羽绒服!"
elif [ $温度 -lt 20 ]; thenecho "🍂 穿外套吧"
elseecho "☀️ 短袖出门~"
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" ]; thenecho "✅ 备份存在"
elseecho "⚠️ 警告:未找到备份文件!"exit 1
fi
2️⃣ 用户输入判断
read -p "今天要带伞吗?(y/n): " 选择
if [ "$选择" = "y" ]; thenecho "🌂 记得放包里"
elif [ "$选择" = "n" ]; thenecho "☀️ 享受晴天吧"
elseecho "输入错误,请重新选择"
fi
3️⃣ 多条件组合
if [ $时间 -gt 6 -a $时间 -lt 18 ]; thenecho "现在是白天"
elif [ $时间 -lt 6 -o $时间 -ge 18 ]; thenecho "现在是夜晚"
fi
⚠️ 天气预测注意事项
-
空格敏感 → 方括号两边必须有空格
❌错误:[$温度<25]
✅正确:[ $温度 -lt 25 ] -
变量防护 → 用双引号包裹变量防止空值
❌危险:[ $文件名 == "test" ]
✅安全:[ "$文件名" == "test" ] -
逻辑运算符
-
-a→ 且(and) -
-o→ 或(or)
-
💡 高级天气预测技巧
-
文件测试:
if [ -d "/data" ]; then # 检查是否是目录echo "找到数据仓库" fi -
字符串比较:
if [ "$OSTYPE" = "linux-gnu" ]; thenecho "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
doecho "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}
doecho "第 $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没加引号!
thenecho "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"
doecho "调试点:当前用户是 $user" >&2 # >&2 表示输出到错误流# ...其他代码...
done
输出👇
调试点:当前用户是 Tom
调试点:当前用户是 Jerry
优点:简单粗暴有效,适合快速测试
调试工具对比表
| 方法 | 适用阶段 | 优点 | 类比 |
|---|---|---|---|
bash -x | 运行时调试 | 全局跟踪执行流程 | 水管全段摄像头 |
set -x | 运行时调试 | 局部精准检查 | 手电筒照特定区域 |
shellcheck | 写代码时 | 提前预防错误 | 施工前的设计检查 |
trap | 运行时错误处理 | 捕捉崩溃瞬间状态 | 汽车黑匣子 |
echo | 任何情况 | 灵活直观 | 贴便签做标记 |
调试小贴士💡:
- 遇到无限循环时,按
Ctrl + C强制终止 - 变量赋值后立即用
echo确认值是否正确 - 复杂脚本用
#注释掉部分代码,分段测试 - 错误信息别怕,先看行号,再检查附近代码
练习:写一个错误脚本(比如计算 1+2 但结果错误),用以上方法调试并修复它!
相关文章:
linux学习(十三)(shell编程(文字,变量,循环,条件,调试))
Shell 编程 Shell 编程,也称为 shell 脚本,是 Linux作系统不可或缺的一部分。shell 脚本实质上是系统 shell 执行的程序。虽然它可能不如 C 或 C 等编译语言强大,但 shell 编程对于管理级任务、自动执行重复性任务和系统监控非常有效。 大多…...
大模型微调中warmup(学习率预热)是什么
大模型微调中warmup(学习率预热)是什么 在大模型微调中,添加warmup(学习率预热)是指在训练初期逐步增加学习率,避免直接使用高学习率导致参数震荡。 🔧 为什么需要warmup? 大模型参数敏感:预训练模型的参数已接近最优,初期用大学习率可能剧烈扰动参数(如“急刹车…...
wireshark 如何关闭混杂模式 wireshark操作
Fiddler和Wireshark都是进行抓包的工具:所谓抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全。抓包也经常被用来进行数据截取等。黑客常常会用抓包软件获取你非加密的上网数据,然后通过分析&#…...
ChatGPT4.5详细介绍和API调用详细教程
OpenAI在2月27日发布GPT-4.5的研究预览版——这是迄今为止OpenAI最强大、最出色的聊天模型。GPT-4.5在扩大预训练和微调规模方面迈出了重要的一步。通过扩大无监督学习的规模,GPT-4.5提升了识别内容中的模式、建立内容关联和生成对于内容的见解的能力,但…...
centos linux安装mysql8 重置密码 远程连接
1. 下载并安装 MySQL Yum 仓库 从 MySQL 官方网站下载并安装 Yum 仓库配置文件。 # 下载MySQL 8.0的Yum仓库包 wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm # 安装Yum仓库包 sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm2. 启…...
AWS 如何导入内部SSL 证书
SSL 证书的很重要的功能就是 HTTP- > HTTPS, 下面就说明一下怎么导入ssl 证书,然后绑定证书到ALB. 以下示例说明如何使用 AWS Management Console 导入证书。 从以下位置打开 ACM 控制台:https://console.aws.amazon.com/acm/home。如果您是首次使用 ACM,请查找 AWS Cer…...
Unity DOTS从入门到精通之 自定义Authoring类
文章目录 前言安装 DOTS 包什么是Authoring1. 实体组件2. Authoring类 前言 DOTS(面向数据的技术堆栈)是一套由 Unity 提供支持的技术,用于提供高性能游戏开发解决方案,特别适合需要处理大量数据的游戏,例如大型开放世…...
一键换肤的Qt-Advanced-Stylesheets
项目简介 能在软件运行时对 CSS 样式表主题(包括 SVG 资源和 SVG 图标)进行实时颜色切换的Qt项目。 项目预览: 项目地址 地址:Qt-Advanced-Stylesheets 本地编译环境 Win11 家庭中文版 Qt5.15.2 (MSVC2019) Qt Creator1…...
golang 静态库 Undefined symbol: __mingw_vfprintf
正常用golang编译一个静态库给 其他语言 调用,编译时报错 Error: Undefined symbol: __mingw_vfprintf 很是奇怪,之前用用golang写静态库成功过,编译也没问题,结果却是截然不同。 试了很多次,发现唯一的差别就是在 …...
宝塔的ssl文件验证域名后,会在域名解析列表中留下记录吗?
在使用宝塔面板进行SSL证书验证域名后,通常不会在域名解析列表中留下记录。验证过程中添加的TXT记录仅用于验证域名的所有权,一旦验证完成,就可以安全地删除这些记录,不会影响SSL证书的正常使用。根据搜索结果,DNS验证…...
Linux 网络:skb 数据管理
文章目录 1. 前言2. skb 数据管理2.1 初始化2.2 数据的插入2.2.1 在头部插入数据2.2.2 在尾部插入数据 2.2 数据的移除 3. 小结 1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. skb 数据管理 数…...
wireguard搭配udp2raw部署内网
前言 上一篇写了使用 wireguard 可以非常轻松的进行组网部署,但是如果服务器厂商屏蔽了 udp 端口,那就没法了 针对 udp 被服务器厂商屏蔽的情况,需要使用一款 udp2raw 或 socat 类似的工具,来将 udp 打包成 tcp 进行通信 这里以…...
Qwen/QwQ-32B 基础模型上构建agent实现ppt自动生成
关心Qwen/QwQ-32B 性能测试结果可以参考下 https://zhuanlan.zhihu.com/p/28600079208https://zhuanlan.zhihu.com/p/28600079208 官方宣传上是该模型性能比肩满血版 DeepSeek-R1(671B)! 我们实现一个 使用Qwen/QwQ-32B 自动生成 PowerPoi…...
【Linux】使用问题汇总
#1 ssh连接的时候报Key exchange failed 原因:服务端版本高,抛弃了一些不安全的交换密钥算法,且客户端版本比较旧,不支持安全性较高的密钥交换算法。 解决方案: 如果是内网应用,安全要求不这么高…...
PostgreSQL17(最新版)安装部署
PostgreSQL 17已与2024年9月26日正式发布!!! 一、Postgres概述 官网地址:PostgreSQL: The world’s most advanced open source database Postgres作为最先进的开源数据库( the latest version of the world’s most…...
【AI大模型智能应用】Deepseek生成测试用例
在软件开发过程中,测试用例的设计和编写是确保软件质量的关键。 然而,软件系统的复杂性不断增加,手动编写测试用例的工作量变得异常庞大,且容易出错。 DeepSeek基于人工智能和机器学习,它能够依据软件的需求和设计文…...
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台 文章目录 准备工作连接设备RTMP概念ENCSHV2推流地址设置大疆Pocket 3直播设置总结 老铁们好! 很久没写软文了,今天给大家带了一个干货,如上图,大疆Pocket 3加ENC编…...
机器人交互系统 部署构建
环境要求 Ubuntu 20.04 或更高版本ROS Noetic 或兼容版本Python 3.8 安装步骤 1. 安装ROS环境(如未安装) sudo apt update sudo apt install ros-noetic-desktop-full source /opt/ros/noetic/setup.bash2. 创建工作空间并克隆代码 mkdir -p ~/code…...
Android Telephony 四大服务和数据网络控制面数据面介绍
在移动通信和Android系统中,涉及的关键概念和服务以及场景案例说明如下: 一、概念 (一)Android Telephony 的四大服务 介绍Telephony Data 与 Android Data 的四大服务在Android系统中,与电话(Telephony)和移动数据(Data)相关的核心服务主要包括以下四类: 1. Tele…...
创建模式-工厂方法模式(Factory Method Pattern)
江城子乙卯正月二十日夜记梦 目的动机简单工厂示例代码 目的 定义一个创建对象的接口,该接口的子类具体负责创建具体的对象。工厂方法模式将对象的实例化延迟到子类。简单工厂是直接在创建方法中负责所有的产品的生成,造成该方法臃肿,并且当…...
文心一言:中国大模型时代的破局者与探路者
2023年,生成式人工智能(AIGC)的浪潮席卷全球,而百度推出的“文心一言”(ERNIE Bot)作为中国AI领域的代表性产品,迅速成为行业焦点。这款基于百度自主研发的“文心大模型”打造的对话式AI工具&am…...
【eNSP实战】交换机配置端口隔离
交换机端口隔离可以实现在同一个VLAN内对端口进行逻辑隔离,端口隔离分为L2层隔离和L3层隔离,这里只进行L2层隔离演示。 拓扑图 路由器AR1配置GE 0/0/1配置IP,其余PC主机各自配置IP和网关。 现将PC1到PC4四个主机全部进行L2层隔离,…...
人脸识别之数据集中 PI20 和 CFMT 之间关联的模型预测贝叶斯(Python+论文代码实现)
代码文件(联系作者点击这里末尾) 代码文件描述如下: subjective_objective.ipynb和:这分别是实际的笔记本和 Web 浏览器友好的只读版本。此笔记本读取数据,执行一些预处理,并包含论文中使用的模型规范。它…...
利用python生成excel中模板范围对应的shape文件
利用python生成excel中模板范围对应的shape文件 # -*- coding: utf-8 -*- import os.pathimport pandas as pd from shapely.geometry import Polygon from shapely.wkt import dumps import argparse# 创建解析器 parser argparse.ArgumentParser(description"这是一个…...
静态时序分析:无法满足的生成时钟(TIM-255警告、UITE-461或PTE-075错误)
相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在阅读本文前,强烈建议首先阅读介绍生成时钟的文章,尤其是其中关于时钟极性和反相的相关内容。 静态时序分析:SDC约束命令cr…...
【亲测有效】Mac系统升级或降级Node.js版本,Mac系统调整node.js版本
有部分兼容性问题需要调整node.js版本 在Mac系统中,升级或降级Node.js版本可以通过使用Node版本管理模块n来实现。以下是具体的步骤: 一、安装Node版本管理模块n 打开终端(Terminal)。 输入以下命令来全局安装n模块: sudo npm install n -g输入后回车,系统会提示输入电…...
maven的项目构建
常用构建命令 命令说明mvn clean清理编译结果(删掉target目录)mvn compile编译核心代码,生成target目录mvn test-compile编译测试代码,生成target目录mvn test执行测试方法mvn package打包,生成jar或war文件mvn insta…...
VSTO(C#)Excel开发2:Excel对象模型和基本操作
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
途游游戏25届AI算法岗内推
熟悉常用的编程语言,如Python、R等,具有良好的编码和调试能力;对常用的机器学习算法和深度学习框架(如TensorFlow、PyTorch等)有深入理解,对大型语言模型有一定了解,具备模型部署和微调的实践经…...
【数据分析大屏】基于Django+Vue汽车销售数据分析可视化大屏(完整系统源码+数据库+开发笔记+详细部署教程+虚拟机分布式启动教程)✅
目录 一、项目背景 二、项目创新点 三、项目功能 四、开发技术介绍 五、项目功能展示 六、权威视频链接 一、项目背景 汽车行业数字化转型加速,销售数据多维分析需求激增。本项目针对传统报表系统交互性弱、实时性差等痛点,基于DjangoVue架构构建…...
