Linux脚本实战:5个高频考点速查手册,面试不慌
版本升级后 API 全变了?别慌,Linux 脚本看似简单,实则坑多。我整理了一份速查手册,直击面试痛点。
考点梳理:面试官最爱问的 5 个死穴
- 权限与执行:为什么
./script.sh报错,bash script.sh却没事? - 变量陷阱:
$1和"$1"有啥区别?什么时候会丢参数? - 循环性能:
for循环调外部命令,为啥慢得像蜗牛? - 错误处理:脚本跑到一半崩了,怎么自动清理临时文件?
- 文本处理三剑客:
awk和sed到底该选谁?
真实案例:上周一个候选人说“脚本出错就
exit 1”,被面试官追问“怎么知道是哪一行错的?”当场卡壳。Stack Overflow 上这个问题热度常年居高不下,说明这是普遍盲区。
标准答法:背下这套逻辑,稳过基础题
1. 权限问题:别被 Permission denied 骗了
错误答案:“加 chmod +x 就行。”
正确答法:
- 检查文件执行位:
ls -l script.sh,看是否有x。 - 检查系统安全策略:SELinux 或 AppArmor 可能拦截。
- 检查路径:
which bash确认解释器存在,$SHELL是否指向正确解释器。 - 关键细节:
./script.sh依赖 shebang 行(#!/bin/bash),而bash script.sh显式指定解释器,绕过了 shebang 检查。
2. 变量引用:双引号是救命稻草
错误答案:$1 就是第一个参数。
正确答法:
echo $1:如果参数含空格(如hello world),会被拆分成两个词。echo "$1":保留原始字符串,防止 word splitting。- 进阶:
$*和$@的区别:"$*":所有参数合并成一个字符串,用第一个分隔符(IFS)连接。"$@":每个参数独立成词,保留原始结构。永远用"$@"传递参数,除非你明确知道自己在干嘛。
3. 循环性能:避免子进程地狱
错误答案:for file in *; do echo $file; done 没问题。
正确答法:
echo是内置命令,没问题。但for file in *; do cat $file; done会 fork 大量子进程,性能爆炸。- 优化方案:
- 用
read内置命令读取:while IFS= read -r line; do ...; done < file - 合并操作:
cat file1 file2 > output比循环cat快 10 倍。 - 避免在循环中调用
ls、grep等外部命令,尽量用find或awk一次性处理。
- 用
4. 错误处理:trap 是你的安全网
错误答案:加 set -e 就行。
正确答法:
set -e:遇到非零退出码立即退出,但无法清理资源。- 标准模板:
#!/bin/bash set -euo pipefailcleanup() {rm -f /tmp/your_script_$$echo "Cleanup done" } trap cleanup EXIT# 你的逻辑 - 关键点:
$$是当前 PID,确保临时文件唯一;trap ... EXIT确保无论成功失败都执行清理。
5. awk vs sed:选错工具事倍功半
错误答案:都能处理文本,看心情。 正确答法:
sed:流编辑器,擅长替换、删除、插入,基于行处理,无状态。awk:编程工具,擅长解析、计算、聚合,有状态(能记住变量)。- 决策树:
- 需要改变量、计数、求和?→
awk - 只需替换/删除固定模式?→
sed - 复杂逻辑?→ 写 Python,别硬扛。
- 需要改变量、计数、求和?→
代码实现:一个能跑的监控脚本
#!/bin/bash
# monitor.sh - 简单磁盘监控脚本
# 用法: ./monitor.sh /dev/sda1 80set -euo pipefail# 参数检查
if [ $# -ne 2 ]; thenecho "Usage: $0 <partition> <threshold_percent>"exit 1
fiPARTITION=$1
THRESHOLD=$2# 检查参数合法性
if ! [[ "$THRESHOLD" =~ ^[0-9]+$ ]]; thenecho "Error: Threshold must be a number"exit 1
fi# 清理函数
cleanup() {if [ -f "/tmp/monitor_$$.log" ]; thenrm -f "/tmp/monitor_$$.log"fi
}
trap cleanup EXIT# 获取当前使用率
USAGE=$(df -h "$PARTITION" | awk 'NR==2 {print $5}' | sed 's/%//')# 比较阈值
if [ "$USAGE" -ge "$THRESHOLD" ]; thenecho "ALERT: $PARTITION usage is ${USAGE}%" | mail -s "Disk Alert" admin@example.comexit 2
elseecho "OK: $PARTITION usage is ${USAGE}%"exit 0
fi
逐行讲解:
set -euo pipefail:-e出错即停,-u未定义变量报错,-o pipefail管道中任一命令失败则整体失败。这是生产环境必备。trap cleanup EXIT:确保临时文件被清理,无论脚本如何退出。awk 'NR==2 {print $5}':取df输出的第二行(数据行)第 5 列(使用率)。sed 's/%//':去掉百分号,方便数字比较。mail -s:发送告警邮件,exit 2表示异常状态,便于监控系统识别。
追问与延伸:面试官的连环炮
追问 1:set -e 有什么坑?
答案:
if cmd; then ... fi中cmd失败不会触发set -e,因为这是条件判断。cmd1 || cmd2中cmd1失败不会触发,因为||处理了错误。- 坑:在管道中,
set -e只检查最后一个命令的退出码,除非加pipefail。
追问 2:如何调试脚本?
答案:
bash -x script.sh:逐行执行并打印。set -x在脚本中开启调试,set +x关闭。- 技巧:在关键位置加
echo "DEBUG: var=$var",比bash -x更精准。
追问 3:Bash 和 Zsh 有什么本质区别?
答案:
- Zsh 是 Bash 的超集,但默认行为不同(如
null_glob、extended_glob)。 - 面试陷阱:说“Zsh 更快”是错的,性能差异微乎其微,主要在于易用性和插件生态。
- 关键点:生产环境用 Bash(兼容性),开发环境用 Zsh(效率)。
追问 4:如何优雅地退出脚本?
答案:
exit 0:成功。exit 1:通用错误。exit 2:参数错误。exit 3:权限错误。- 最佳实践:定义自定义退出码,并在文档中说明,便于自动化系统解析。
记忆口诀:5 个关键点,考场不翻车
- 权限看三样:文件位、系统策略、解释器路径。
- 变量加双引:
"$var"保平安,防拆分、防通配。 - 循环避子进程:内置命令优先,合并操作提性能。
- trap 管清理:
EXIT钩子兜底,临时文件不留痕。 - awk 算数 sed 改:有状态用 awk,纯替换用 sed。
最后提醒:面试不是背八股,而是展示排查问题的思路。当被问到时,先说“我会先检查 X,再验证 Y,最后确认 Z”,比直接甩答案更显专业。
这个知识点你面试被问过吗?留言说说