
Shell脚本是Linux运维的必备技能。本文从基础语法到实战案例,帮你快速掌握Shell脚本编程。
一、脚本基础
#!/bin/bash # 这是一个Shell脚本 # 第一行指定解释器 # 赋予执行权限 chmod +x script.sh # 执行脚本 ./script.sh # 或 bash script.sh
二、变量
# 定义变量(等号两边不能有空格)name="hello"
age=25使用变量
echo $name
echo ${name}只读变量
readonly PI=3.14
删除变量
unset name
字符串操作
greeting="Hello World"
echo ${#greeting} # 长度:11
echo ${greeting:0:5} # 截取:Hello
echo ${greeting/World/Linux} # 替换:Hello Linux特殊变量
echo $0 # 脚本名称
echo $1 # 第一个参数
echo $2 # 第二个参数
echo $# # 参数个数
echo $@ # 所有参数
echo $? # 上个命令的退出状态
echo $$ # 当前进程ID
三、条件判断
# if语句
if [ $age -ge 18 ]; then
echo "成年人"
elif [ $age -ge 12 ]; then
echo "青少年"
else
echo "儿童"
fi常用比较运算符
-eq 等于 # -ne 不等于
-gt 大于 # -lt 小于
-ge 大于等于 # -le 小于等于
字符串比较
if [ "$name" = "hello" ]; then
echo "匹配"
fiif [ -z "$str" ]; then
echo "字符串为空"
fi文件判断
if [ -f "/etc/passwd" ]; then
echo "文件存在"
fi
if [ -d "/tmp" ]; then
echo "目录存在"
fi
if [ -r "file.txt" ]; then
echo "文件可读"
ficase语句
case $1 in
start)
echo "启动服务"
;;
stop)
echo "停止服务"
;;
restart)
echo "重启服务"
;;
*)
echo "用法: $0 {start|stop|restart}"
;;
esac
四、循环
# for循环
for i in 1 2 3 4 5; do
echo "数字: $i"
done范围循环
for i in {1..10}; do
echo $i
doneC风格for循环
for ((i=0; i<10; i++)); do
echo $i
done遍历文件
for file in /var/log/*.log; do
echo "处理: $file"
donewhile循环
count=0
while [ $count -lt 5 ]; do
echo "计数: $count"
count=$((count + 1))
done读取文件每一行
while IFS= read -r line; do
echo "$line"
done < /etc/passwduntil循环(条件为假时执行)
until [ $count -ge 10 ]; do
echo $count
count=$((count + 1))
done
五、函数
# 定义函数
function greet() {
echo "Hello, $1!"
return 0
}调用函数
greet "World"
带返回值的函数
add() {
local result=$(($1 + $2))
echo $result
}获取函数输出
sum=$(add 3 5)
echo "3 + 5 = $sum"local变量(函数内局部变量)
myfunc() {
local local_var="我是局部变量"
echo $local_var
}默认参数
greet() {
local name=${1:-"World"}
echo "Hello, $name!"
}
六、输入输出
# 读取用户输入
read -p "请输入用户名: " username
echo "你好, $username"静默输入(密码)
read -s -p "请输入密码: " password
echo输出重定向
echo "hello" > file.txt # 覆盖写入
echo "world" >> file.txt # 追加写入错误重定向
command 2> error.log # 错误输出到文件
command > output.log 2>&1 # 所有输出到文件
command &> all.log # 同上管道
cat /etc/passwd | grep root | wc -l
Here Document
cat < EOF
这是多行
文本内容
EOF
七、实战案例
案例1:服务器巡检脚本
#!/bin/bashserver_check.sh - 服务器巡检
HOSTNAME=$(hostname)
DATE=$(date +"%Y-%m-%d %H:%M:%S")
UPTIME=$(uptime -p)
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')
MEM_USAGE=$(free | grep Mem | awk '{printf("%.1f%%", $3/$2*100)}')
DISK_USAGE=$(df -h / | awk 'NR==2{print $5}')
LOAD=$(cat /proc/loadavg | awk '{print $1, $2, $3}')========================================="
echo "服务器巡检报告"
echo "时间: $DATE"
echo "主机名: $HOSTNAME"
echo "运行时间: $UPTIME"
echo "CPU使用率: ${CPU_USAGE}%"
echo "内存使用率: $MEM_USAGE"
echo "磁盘使用率: $DISK_USAGE"
echo "系统负载: $LOAD"
========================================="检查磁盘使用率
DISK_NUM=$(echo $DISK_USAGE | tr -d '%')
if [ $DISK_NUM -gt 80 ]; then
echo "[警告] 磁盘使用率超过80%!"
fi
案例2:批量创建用户
#!/bin/bashbatch_user.sh - 批量创建用户
USER_LIST="user_list.txt"
PASSWORD="Temp@123"while IFS= read -r username; do
if id "$username" &>/dev/null; then
echo "用户 $username 已存在"
else
useradd -m -s /bin/bash "$username"
echo "$username:$PASSWORD" | chpasswd
echo "用户 $username 创建成功"
fi
done < $USER_LIST
案例3:日志清理脚本
#!/bin/bashlog_clean.sh - 清理N天前的日志
LOG_DIR="/var/log/app"
KEEP_DAYS=30
DATE=$(date +"%Y-%m-%d %H:%M:%S")echo "[$DATE] 开始清理${KEEP_DAYS}天前的日志..."
删除旧日志
DELETED=$(find $LOG_DIR -name "*.log" -mtime +$KEEP_DAYS -delete -print | wc -l)
echo "[$DATE] 清理完成,删除了 $DELETED 个文件"
清空大于100M的日志
find $LOG_DIR -name "*.log" -size +100M -exec truncate -s 0 {} \;
echo "[$DATE] 已清空大于100M的日志文件"
八、调试技巧
# 开启调试模式
bash -x script.sh或在脚本中开启
set -x # 开启调试
set +x # 关闭调试遇到错误立即退出
set -e
使用未定义变量时报错
set -u
组合使用
set -euo pipefail
Shell脚本看似简单,但用好了能极大提高运维效率。建议从实际需求出发,边学边写,逐步积累。
评论