12. Shell 脚本基础
12.1 第一个脚本
bash
#!/bin/bash
# 这是我的第一个 Shell 脚本
# 文件名:hello.sh
echo "Hello, Linux World!"
echo "当前时间: $(date)"
echo "当前用户: $(whoami)"
echo "主机名: $(hostname)"bash
# 给脚本添加执行权限并运行
chmod +x hello.sh
./hello.shbash
$ ./hello.sh
Hello, Linux World!
当前时间: Sat Jun 20 10:30:00 CST 2026
当前用户: user
主机名: myserver12.2 变量
bash
#!/bin/bash
# 变量示例
# 定义变量(等号两边不能有空格!)
NAME="Linux"
VERSION=6.5
TODAY=$(date +%Y-%m-%d)
# 使用变量
echo "系统: $NAME"
echo "版本: ${VERSION}" # 花括号可选,用于消除歧义
echo "日期: $TODAY"
# 只读变量
readonly PI=3.14159
# 删除变量(只读变量无法删除)
unset NAME
# 特殊变量
echo "脚本名: $0"
echo "参数个数: $#"
echo "所有参数: $@"
echo "上一条命令的返回值: $?"
echo "当前进程 PID: $$"
# 字符串操作
STR="Hello World"
echo "长度: ${#STR}" # 11
echo "子串: ${STR:0:5}" # Hello
echo "替换: ${STR/World/Linux}" # Hello Linux12.3 条件判断
bash
#!/bin/bash
# 条件判断示例
# if-elif-else
AGE=25
if [ $AGE -lt 18 ]; then
echo "未成年"
elif [ $AGE -ge 18 ] && [ $AGE -lt 60 ]; then
echo "成年人"
else
echo "老年人"
fi
# 文件测试
FILE="/etc/passwd"
if [ -f "$FILE" ]; then
echo "$FILE 是普通文件"
fi
if [ -d "/home/user" ]; then
echo "家目录存在"
fi
if [ -r "$FILE" ]; then
echo "文件可读"
fi
if [ -x "/bin/ls" ]; then
echo "ls 命令可执行"
fi
# 字符串比较
STR="hello"
if [ "$STR" = "hello" ]; then
echo "字符串相等"
fi
if [ -z "$EMPTY" ]; then
echo "变量为空"
fi
# 更现代的写法(双括号)
if [[ "$STR" == h* ]]; then
echo "以 h 开头"
fi
# case 语句
case "$1" in
start)
echo "启动服务"
;;
stop)
echo "停止服务"
;;
restart)
echo "重启服务"
;;
*)
echo "用法: $0 {start|stop|restart}"
exit 1
;;
esac12.4 循环
bash
#!/bin/bash
# 循环示例
# for 循环 — 列表形式
for color in red green blue; do
echo "颜色: $color"
done
# for 循环 — C 风格
for ((i=1; i<=5; i++)); do
echo "数字: $i"
done
# for 循环 — 遍历文件
for file in /var/log/*.log; do
echo "日志文件: $file"
done
# while 循环
COUNT=1
while [ $COUNT -le 5 ]; do
echo "计数: $COUNT"
((COUNT++))
done
# while 读取文件每一行
while IFS= read -r line; do
echo "行内容: $line"
done < /etc/hostname
# until 循环(条件为假时执行)
NUM=10
until [ $NUM -le 0 ]; do
echo -n "$NUM "
((NUM--))
done
echo ""
# break 和 continue
for i in {1..10}; do
if [ $i -eq 5 ]; then
continue # 跳过5
fi
if [ $i -eq 8 ]; then
break # 到8就停
fi
echo $i
donebash
$ ./loops.sh
颜色: red
颜色: green
颜色: blue
数字: 1
数字: 2
数字: 3
数字: 4
数字: 5
计数: 1
计数: 2
计数: 3
计数: 4
计数: 5
10 9 8 7 6 5 4 3 2 1
1
2
3
4
6
712.5 函数
bash
#!/bin/bash
# 函数示例
# 定义函数
greet() {
local name=$1 # local 声明局部变量
local time=$(date +%H)
if [ $time -lt 12 ]; then
echo "早上好,$name!"
elif [ $time -lt 18 ]; then
echo "下午好,$name!"
else
echo "晚上好,$name!"
fi
return 0
}
# 调用函数
greet "小明"
greet "小红"
# 带返回值的函数
add() {
local sum=$(( $1 + $2 ))
echo $sum # 通过 echo 返回结果
}
result=$(add 3 5)
echo "3 + 5 = $result"
# 实用函数:检查命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
echo "错误: $1 未安装"
return 1
else
echo "✓ $1 已安装: $(which $1)"
return 0
fi
}
check_command git
check_command docker
check_command nonexistent_cmdbash
$ ./functions.sh
下午好,小明!
下午好,小红!
3 + 5 = 8
✓ git 已安装: /usr/bin/git
✓ docker 已安装: /usr/bin/docker
错误: nonexistent_cmd 未安装12.6 实战脚本:系统信息报告
bash
#!/bin/bash
# sysinfo.sh — 系统信息报告脚本
echo "========================================="
echo " 系统信息报告 - $(date)"
echo "========================================="
echo ""
echo "--- 主机信息 ---"
echo "主机名: $(hostname)"
echo "内核版本: $(uname -r)"
echo "操作系统: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "运行时间: $(uptime -p)"
echo ""
echo "--- CPU 信息 ---"
echo "型号: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
echo "核心数: $(nproc)"
echo "负载: $(cat /proc/loadavg | awk '{print $1, $2, $3}')"
echo ""
echo "--- 内存使用 ---"
free -h | grep -v Swap
echo ""
echo "--- 磁盘使用 ---"
df -hT | grep -v tmpfs | grep -v devtmpfs
echo ""
echo "--- 网络接口 ---"
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print $2, $NF}'
echo ""
echo "--- Top 5 进程(内存) ---"
ps aux --sort=-%mem | awk 'NR<=6 {printf "%-10s %-8s %-6s %s\n", $1, $3"%", $4"%", $11}'
echo ""
echo "========================================="
echo " 报告生成完毕"
echo "========================================="bash
$ chmod +x sysinfo.sh && ./sysinfo.sh
-----------------------------------------
系统信息报告 - Sat Jun 20 10:30:00 CST 2026
-----------------------------------------
--- 主机信息 ---
主机名: myserver
内核版本: 5.15.0-91-generic
操作系统: Ubuntu 22.04.3 LTS
运行时间: up 15 hours, 23 minutes
--- CPU 信息 ---
型号: Intel(R) Core(TM) i7-12700H
核心数: 8
负载: 0.52 0.48 0.35
--- 内存使用 ---
total used free shared buff/cache available
Mem: 3.8Gi 2.7Gi 156Mi 128Mi 999Mi
--- 磁盘使用 ---
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 22G 26G 46% /
/dev/sda2 ext4 200G 156G 34G 83% /home
--- 网络接口 ---
192.168.1.100/24 eth0
--- Top 5 进程(内存) ---
root 2.3% 12.5% /usr/sbin/mysqld
www-data 0.5% 8.2% apache2
root 0.1% 3.1% /usr/bin/dockerd
user 1.2% 2.8% vim
-----------------------------------------
报告生成完毕
-----------------------------------------