Shell脚本是Linux日常运维和自动化的基本功,掌握基础语法就能大幅提升效率。
基本结构
#!/bin/bash
# 第一行shebang声明解释器
echo "Hello, Shell!"
赋予执行权限后运行:
chmod +x hello.sh
./hello.sh
变量
# 定义(等号两侧不能有空格)
name="world"
count=42
# 使用
echo "Hello, $name"
echo "Count is ${count} items"
# 只读
readonly PI=3.14
# 命令替换
current_date=$(date +%Y-%m-%d)
file_count=$(ls | wc -l)
条件判断
if语句
#!/bin/bash
if [ -f "/etc/nginx/nginx.conf" ]; then
echo "Nginx config exists"
elif [ -f "/etc/apache2/apache2.conf" ]; then
echo "Apache config exists"
else
echo "No web server config found"
fi
常用判断:
-f file:文件存在且是普通文件-d dir:目录存在-z "$str":字符串为空-n "$str":字符串非空$a -eq $b:数值相等$a -gt $b:数值大于
case语句
#!/bin/bash
case "$1" in
start)
echo "Starting service..."
;;
stop)
echo "Stopping service..."
;;
restart)
echo "Restarting service..."
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
循环
# for循环
for file in /var/log/*.log; do
echo "Processing $file"
wc -l "$file"
done
# 遍历序列
for i in $(seq 1 5); do
echo "Number: $i"
done
# while循环:逐行读取文件
while IFS= read -r line; do
echo "Line: $line"
done < /etc/hosts
# while计数
count=0
while [ $count -lt 10 ]; do
echo $count
count=$((count + 1))
done
函数
#!/bin/bash
check_disk() {
local threshold=${1:-80}
local usage=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$usage" -gt "$threshold" ]; then
echo "WARNING: Disk usage ${usage}% exceeds ${threshold}%"
return 1
else
echo "OK: Disk usage ${usage}%"
return 0
fi
}
# 调用
check_disk 90
实用示例:日志清理脚本
#!/bin/bash
# clean_logs.sh - 清理指定天数前的日志文件
LOG_DIR="/var/log/app"
DAYS=7
if [ ! -d "$LOG_DIR" ]; then
echo "Directory $LOG_DIR does not exist"
exit 1
fi
echo "Cleaning logs older than $DAYS days in $LOG_DIR"
deleted=0
while IFS= read -r -d '' file; do
echo "Deleting: $file"
rm -f "$file"
deleted=$((deleted + 1))
done < <(find "$LOG_DIR" -name "*.log" -mtime +$DAYS -print0)
echo "Done. Deleted $deleted files."
实用示例:批量备份MySQL数据库
#!/bin/bash
# backup_mysql.sh
BACKUP_DIR="/data/backup/mysql/$(date +%Y%m%d)"
MYSQL_USER="backup"
MYSQL_PASS="secret"
mkdir -p "$BACKUP_DIR"
databases=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -e "SHOW DATABASES;" | grep -Ev "^(Database|information_schema|performance_schema|sys)$")
for db in $databases; do
echo "Backing up $db..."
mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASS" "$db" | gzip > "${BACKUP_DIR}/${db}.sql.gz"
done
echo "Backup completed: $BACKUP_DIR"
写Shell脚本记住两点:加set -euo pipefail防止静默失败,变量加双引号防止分词问题。