Shell脚本编程入门:变量、循环、函数与实战案例

运维  ·  2026-06-26

Shell

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 "匹配"
fi

if [ -z "$str" ]; then
    echo "字符串为空"
fi

 文件判断

if [ -f "/etc/passwd" ]; then
    echo "文件存在"
fi
if [ -d "/tmp" ]; then
    echo "目录存在"
fi
if [ -r "file.txt" ]; then
    echo "文件可读"
fi

 case语句

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
done

 C风格for循环

for ((i=0; i<10; i++)); do
    echo $i
done

 遍历文件

for file in /var/log/*.log; do
    echo "处理: $file"
done

 while循环

count=0
while [ $count -lt 5 ]; do
    echo "计数: $count"
    count=$((count + 1))
done

 读取文件每一行

while IFS= read -r line; do
    echo "$line"
done < /etc/passwd

 until循环(条件为假时执行)

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/bash

 server_check.sh - 服务器巡检

HOSTNAME=$(hostname)
DATE=$(date +"%Y-%m-%d %H:%M:%S")
UPTIME=$(uptime -p)
CPU_USAGE=$(top&nbsp;-bn1&nbsp;|&nbsp;grep&nbsp;&quot;Cpu(s)&quot;&nbsp;|&nbsp;awk&nbsp;&#39;{print&nbsp;$2}')
MEM_USAGE=$(free&nbsp;|&nbsp;grep&nbsp;Mem&nbsp;|&nbsp;awk&nbsp;&#39;{printf(&quot;%.1f%%&quot;,&nbsp;$3/$2*100)}')
DISK_USAGE=$(df&nbsp;-h&nbsp;/&nbsp;|&nbsp;awk&nbsp;&#39;NR==2{print&nbsp;$5}')
LOAD=$(cat&nbsp;/proc/loadavg&nbsp;|&nbsp;awk&nbsp;&#39;{print&nbsp;$1, $2,&nbsp;$3}')

========================================="
echo "服务器巡检报告"
echo "时间: $DATE"
echo "主机名: $HOSTNAME"
echo "运行时间: $UPTIME"
echo "CPU使用率: ${CPU_USAGE}%"
echo "内存使用率: $MEM_USAGE"
echo "磁盘使用率: $DISK_USAGE"
echo "系统负载: $LOAD"
========================================="

 检查磁盘使用率

DISK_NUM=$(echo&nbsp;$DISK_USAGE | tr -d '%')
if [ $DISK_NUM -gt 80 ]; then
    echo "[警告] 磁盘使用率超过80%!"
fi

案例2:批量创建用户

#!/bin/bash

 batch_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/bash

 log_clean.sh - 清理N天前的日志

LOG_DIR="/var/log/app"
KEEP_DAYS=30
DATE=$(date +"%Y-%m-%d %H:%M:%S")

echo "[$DATE]&nbsp;开始清理${KEEP_DAYS}天前的日志..."

 删除旧日志

DELETED=$(find&nbsp;$LOG_DIR -name "*.log" -mtime +$KEEP_DAYS -delete -print | wc -l)

echo "[$DATE]&nbsp;清理完成,删除了&nbsp;$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脚本看似简单,但用好了能极大提高运维效率。建议从实际需求出发,边学边写,逐步积累。

评论
远方. All Rights Reserved. Theme Jasmine by Kent Liao.