Shell 脚本核心速查(Bash)¶
用途:供 AI 助手快速查阅并编写/调试运维脚本。 版本基线:Ubuntu 26.04 LTS / bash 5.3 / Git 2.56(核对日期 2026-11-11,来源:官网) 更新日期:2026-11-11
1. 脚本骨架(规范模板)¶
#!/usr/bin/env bash
set -euo pipefail # e:出错即退 u:未定义变量报错 pipefail:管道任一环节失败即失败
# 用法说明
usage() { echo "Usage: $0 <arg1> <arg2>"; exit 1; }
[ $# -lt 1 ] && usage
ARG1="$1"
log() { echo "[$(date '+%F %T')] $*"; } # 简易日志函数
trap 'log "脚本异常退出于第 $LINENO 行"' ERR # 出错打印行号
执行:chmod +x script.sh && ./script.sh;调试:bash -x script.sh(打印每条命令)。
bash 5.3(2025-05,最新稳定版)值得关注的点:新增在当前 shell 执行上下文中运行的命令替换
(不 fork 子进程、可改变当前 shell 变量)、GLOBSORT 变量控制路径补全排序、read -E 带补全读入。
以上均为增强特性,既有脚本语法(5.x 全系兼容)不受影响。
2. 变量与字符串¶
NAME="world"
echo "hello $NAME" # 双引号内展开变量
echo 'hello $NAME' # 单引号不展开(字面量)
echo "${NAME}!" # 拼接时用花括号防歧义
DEFAULT="${1:-fallback}" # 参数缺省值
LENGTH=${#NAME} # 字符串长度
SUB=${NAME:0:3} # 截取
UPPER=${NAME^^} # 转大写(bash4+)
命令替换:NOW=$(date +%F) # 用 $() 不用反引号
3. 条件判断¶
# 文件测试
[ -f file ] # 存在且是文件 [ -d dir ] 存在且是目录
[ -z "$s" ] # 空字符串 [ -n "$s" ] 非空
[ -x script ] # 可执行 [ -w f ] 可写
# 字符串 / 数字
[ "$a" = "$b" ] # 相等(字符串一律加引号)
[ "$n" -gt 10 ] # -gt -lt -ge -le -eq -ne
# 推荐 [[ ]](更安全,支持正则与 && ||)
if [[ "$str" =~ ^[0-9]+$ ]]; then echo "是数字"; fi
if [[ -f "$file" && "$user" == "root" ]]; then :; fi
# 分支
case "$1" in
start) echo start ;;
stop) echo stop ;;
*) echo "unknown" ;;
esac
4. 循环¶
for i in 1 2 3; do echo $i; done
for i in {1..10}; do echo $i; done
for f in /var/log/*.log; do wc -l "$f"; done
for ip in 192.168.100.{1..10}; do ping -c1 -W1 $ip & done; wait # 并发 ping
while read -r line; do echo "$line"; done < file.txt
while true; do date; sleep 5; done # 守护式轮询(实验用)
5. 函数与返回值¶
myfunc() {
local x="$1" # 局部变量
echo "$((x * 2))" # stdout 是返回值的方式之一
return 0 # return 只表示成功/失败(0-255)
}
result=$(myfunc 21) # 捕获 stdout
myfunc 21 && echo ok # 用 exit code 判断
6. 常用文本处理¶
cat file | grep -v "^#" | grep -v "^$" # 去掉注释和空行
awk '{print $1, $3}' access.log # 按列取
awk -F: '$3 >= 1000 {print $1}' /etc/passwd # 自定义分隔符
sed -i 's/old/new/g' file # 原地替换(先不带 i 预览!)
sed -n '10,20p' file # 取第 10-20 行
cut -d, -f1,3 data.csv # CSV 取列
sort -u file | wc -l # 去重计数
sort file | uniq -c | sort -rn | head # Top N 频次
jq '.items[].metadata.name' a.json # JSON 处理(apt install jq)
xargs -I{} cp {} /backup/ # 把上一步结果逐个处理
7. 实用运维脚本片段¶
# 磁盘告警
df -H | awk 'NR>1 {gsub("%","",$5); if ($5+0 > 85) print $6" 使用率 "$5"%" }'
# 判断服务活着,死了自动拉起
systemctl is-active --quiet nginx || systemctl restart nginx
# 备份并保留最近 7 份
tar -czf /backup/app-$(date +%F).tar.gz /opt/app/data
ls -1t /backup/app-*.tar.gz | tail -n +8 | xargs -r rm -f
# 等待端口可用(部署后健康检查)
until curl -sf http://localhost:8080/health >/dev/null; do sleep 2; done
8. AI 助手操作守则¶
- 生成脚本必带
set -euo pipefail和#!/usr/bin/env bash。 - 写入非 ASCII 路径/内容时注意编码(Windows 下用 UTF-8 无 BOM;避免生成 .ps1/.bat 中文脚本,Linux 端一律 .sh)。
sed -i修改文件前先输出替换结果预览,或先备份。rm相关脚本片段必须带精确路径或-r前有明确清单,禁止rm $VAR/*这类未判空写法(先[ -n "$VAR" ])。- 脚本执行前
bash -n script.sh做语法检查,shellcheck可用时优先跑一遍。 - 长时间/循环类脚本要留日志输出(重定向到文件),便于事后
tail排查。