2026-01-23
最近更新:Linux基础教程 第18课:Linux云计算基础
2026-01-23
2026-01-23
2026-01-23
最近更新:Linux基础教程 第15课:Linux内核和驱动管理
2026-01-21
浏览量:44 次 发布时间:2026-01-18 14:36 作者:明扬工控商城 下载docx
2026-01-23
最近更新:Linux基础教程 第18课:Linux云计算基础
2026-01-23
2026-01-23
2026-01-23
最近更新:Linux基础教程 第15课:Linux内核和驱动管理
2026-01-21
好的,我们继续第七课。今天学习Shell脚本编程,这是Linux自动化的重要技能。
第一部分:什么是Shell脚本?
1.1 Shell脚本的概念
Shell脚本就是把一系列Linux命令写在一个文件里,让Shell一次性执行。
为什么要学?
自动化重复任务
批量处理文件
定时执行任务
简化复杂操作
1.2 第一个Shell脚本
我们创建一个最简单的脚本:
bash
# 1. 创建脚本文件
cd ~
vim first_script.sh
在vim中按 i 进入插入模式,输入:
bash
#!/bin/bash
# 这是我的第一个Shell脚本
echo "Hello, Shell Scripting!"
echo "当前时间是: $(date)"
echo "当前用户是: $(whoami)"
echo "当前目录是: $(pwd)"
按 ESC 键,然后输入 :wq 保存退出。
1.3 运行脚本的三种方法
bash
# 方法1:用bash命令执行(不需要执行权限)
bash first_script.sh
# 方法2:给执行权限后直接运行
chmod +x first_script.sh
./first_script.sh
# 方法3:用source或.执行(在当前Shell环境执行)
source first_script.sh
# 或
. first_script.sh
注意:
#! 叫做shebang,告诉系统用哪个解释器
注释用 #
$() 是命令替换,执行命令并用结果替换
第二部分:变量
2.1 定义变量
bash
# 创建脚本 variable_demo.sh
vim variable_demo.sh
输入内容:
bash
#!/bin/bash
# 定义变量(等号两边不能有空格!)
name="张三"
age=25
work="Linux系统管理员"
# 使用变量
echo "姓名: $name"
echo "年龄: $age"
echo "职业: $work"
echo "欢迎 $name 学习Shell脚本!"
# 只读变量(不能修改)
readonly PI=3.14159
echo "圆周率: $PI"
# PI=3.14 # 这行会报错
运行测试:
bash
chmod +x variable_demo.sh
./variable_demo.sh
2.2 变量的使用
bash
#!/bin/bash
# 1. 使用花括号(变量名边界清晰)
fruit="apple"
echo "我有1个${fruit}" # 正确:我有1个apple
echo "我有1个$fruit" # 也可以,但有时会混淆
# 2. 变量重新赋值
count=10
echo "数量: $count"
count=20
echo "新数量: $count"
# 3. 命令执行结果赋值
current_date=$(date)
echo "当前时间: $current_date"
files_in_home=$(ls ~)
echo "家目录文件:"
echo "$files_in_home"
2.3 特殊变量
bash
#!/bin/bash
echo "脚本名: $0" # 脚本名称
echo "第一个参数: $1" # 第一个参数
echo "第二个参数: $2" # 第二个参数
echo "所有参数: $@" # 所有参数列表
echo "参数个数: $#" # 参数个数
echo "当前进程ID: $$" # 进程ID
echo "上一条命令退出状态: $?" # 0表示成功,非0表示失败
# 运行测试
# ./script.sh arg1 arg2 arg3
创建一个测试脚本:
bash
vim special_vars.sh
输入:
bash
#!/bin/bash
echo "===== 特殊变量演示 ====="
echo "你执行了: $0"
echo "你传了 $# 个参数"
echo "参数列表: $@"
if [ $# -gt 0 ]; then
echo "第一个参数是: $1"
else
echo "你没有传参数"
fi
echo "进程ID: $$"
ls /tmp # 正常命令
echo "ls命令结果: $?"
ls /nonexist # 错误命令
echo "错误命令结果: $?"
运行测试:
bash
chmod +x special_vars.sh
./special_vars.sh hello world 123
第三部分:用户输入
3.1 从命令行参数获取
bash
#!/bin/bash
# 保存为 args_demo.sh
echo "开始处理用户信息..."
# 检查参数个数
if [ $# -lt 2 ]; then
echo "用法: $0 <姓名> <年龄>"
exit 1 # 退出脚本,1表示错误
fi
name=$1
age=$2
echo "姓名: $name"
echo "年龄: $age"
# 年龄判断
if [ $age -lt 18 ]; then
echo "$name 是未成年人"
elif [ $age -lt 60 ]; then
echo "$name 是成年人"
else
echo "$name 是老年人"
fi
运行:
bash
./args_demo.sh 李四 25
./args_demo.sh # 不传参数测试
3.2 运行时读取输入
bash
#!/bin/bash
# 保存为 read_input.sh
echo "=== 用户注册 ==="
# 读取输入
read -p "请输入用户名: " username
read -p "请输入邮箱: " email
read -sp "请输入密码: " password # -s表示隐藏输入
echo # 换行
echo "注册成功!"
echo "用户名: $username"
echo "邮箱: $email"
echo "密码长度: ${#password} 位"
3.3 读取多个值
bash
#!/bin/bash
echo "请输入你的姓名、年龄和城市(用空格分隔):"
read name age city
echo "你好 $name"
echo "年龄: $age"
echo "城市: $city"
# 读取数组
echo "请输入你喜欢的编程语言(多个用空格分隔):"
read -a languages
echo "你喜欢的语言有 ${#languages[@]} 种:"
for lang in "${languages[@]}"; do
echo " - $lang"
done
第四部分:条件判断
4.1 基本if语句
bash
#!/bin/bash
# 判断文件是否存在
if [ -f ~/.bashrc ]; then
echo "bashrc文件存在"
else
echo "bashrc文件不存在"
fi
# 判断目录是否存在
if [ -d ~/Documents ]; then
echo "Documents目录存在"
fi
# 判断字符串
read -p "请输入(yes/no): " answer
if [ "$answer" = "yes" ]; then
echo "你选择了是"
elif [ "$answer" = "no" ]; then
echo "你选择了否"
else
echo "输入无效"
fi
4.2 文件测试操作符
bash
#!/bin/bash
file="/etc/passwd"
if [ -e "$file" ]; then echo "文件存在"; fi
if [ -f "$file" ]; then echo "是普通文件"; fi
if [ -d "$file" ]; then echo "是目录"; fi
if [ -r "$file" ]; then echo "可读"; fi
if [ -w "$file" ]; then echo "可写"; fi
if [ -x "$file" ]; then echo "可执行"; fi
if [ -s "$file" ]; then echo "文件大小不为空"; fi
4.3 数值比较
bash
#!/bin/bash
read -p "请输入第一个数字: " num1
read -p "请输入第二个数字: " num2
echo "比较结果:"
if [ $num1 -eq $num2 ]; then echo "$num1 等于 $num2"; fi
if [ $num1 -ne $num2 ]; then echo "$num1 不等于 $num2"; fi
if [ $num1 -gt $num2 ]; then echo "$num1 大于 $num2"; fi
if [ $num1 -lt $num2 ]; then echo "$num1 小于 $num2"; fi
if [ $num1 -ge $num2 ]; then echo "$num1 大于等于 $num2"; fi
if [ $num1 -le $num2 ]; then echo "$num1 小于等于 $num2"; fi
4.4 字符串比较
bash
#!/bin/bash
read -p "请输入第一个字符串: " str1
read -p "请输入第二个字符串: " str2
echo "字符串比较:"
if [ "$str1" = "$str2" ]; then echo "字符串相同"; fi
if [ "$str1" != "$str2" ]; then echo "字符串不同"; fi
if [ -z "$str1" ]; then echo "str1是空字符串"; fi
if [ -n "$str2" ]; then echo "str2是非空字符串"; fi
if [ "$str1" > "$str2" ]; then echo "str1在字典序中大于str2"; fi
if [ "$str1" < "$str2" ]; then echo "str1在字典序中小于str2"; fi
第五部分:循环
5.1 for循环
bash
#!/bin/bash
echo "=== 基本for循环 ==="
for i in 1 2 3 4 5; do
echo "数字: $i"
done
echo "=== 遍历文件 ==="
for file in ~/*.sh; do
if [ -f "$file" ]; then
echo "找到脚本: $(basename "$file")"
fi
done
echo "=== 序列循环 ==="
for i in {1..5}; do
echo "计数: $i"
done
for i in {1..10..2}; do # 1到10,步长为2
echo "奇数: $i"
done
echo "=== C风格for循环 ==="
for ((i=1; i<=5; i++)); do
echo "C风格: $i"
done
5.2 while循环
bash
#!/bin/bash
echo "=== while循环 ==="
count=1
while [ $count -le 5 ]; do
echo "计数: $count"
count=$((count + 1))
done
echo "=== 读取文件行 ==="
echo "创建测试文件..."
cat > test_file.txt << EOF
第一行
第二行
第三行
第四行
EOF
echo "逐行读取:"
while IFS= read -r line; do
echo "行内容: $line"
done < test_file.txt
echo "=== 无限循环(按Ctrl+C停止)==="
# while true; do
# echo "当前时间: $(date)"
# sleep 1 # 等待1秒
# done
5.3 until循环
bash
#!/bin/bash
echo "=== until循环 ==="
count=1
until [ $count -gt 5 ]; do
echo "计数: $count"
count=$((count + 1))
done
# until和while相反
# while: 条件为真时执行
# until: 条件为假时执行
第六部分:函数
6.1 定义和调用函数
bash
#!/bin/bash
# 定义函数
say_hello() {
echo "你好,$1!"
echo "欢迎学习Shell脚本!"
}
# 带返回值的函数
add() {
local result=$(( $1 + $2 )) # local表示局部变量
return $result
}
# 调用函数
echo "=== 函数演示 ==="
say_hello "张三"
# 调用有返回值的函数
add 10 20
echo "10 + 20 = $?"
6.2 更实用的函数例子
bash
#!/bin/bash
# 检查服务状态的函数
check_service() {
if systemctl is-active --quiet "$1"; then
echo "服务 $1 正在运行"
return 0
else
echo "服务 $1 未运行"
return 1
fi
}
# 备份文件的函数
backup_file() {
local src="$1"
local dest="${src}.backup.$(date +%Y%m%d_%H%M%S)"
if [ ! -f "$src" ]; then
echo "错误:文件 $src 不存在"
return 1
fi
cp "$src" "$dest"
if [ $? -eq 0 ]; then
echo "备份成功: $src -> $dest"
return 0
else
echo "备份失败"
return 1
fi
}
# 使用函数
echo "=== 检查服务 ==="
check_service ssh
check_service nginx
echo "=== 备份文件 ==="
backup_file ~/.bashrc
第七部分:实用脚本示例
示例1:系统信息收集脚本
bash
#!/bin/bash
# 保存为 system_info.sh
collect_system_info() {
echo "====== 系统信息报告 ======"
echo "生成时间: $(date)"
echo ""
echo "1. 系统信息"
echo " 主机名: $(hostname)"
echo " 内核版本: $(uname -r)"
echo " 系统版本: $(lsb_release -d | cut -f2)"
echo ""
echo "2. 硬件信息"
echo " CPU型号: $(lscpu | grep "Model name" | cut -d: -f2 | sed 's/^ *//')"
echo " CPU核心数: $(nproc)"
echo " 内存总量: $(free -h | awk '/Mem:/ {print $2}')"
echo " 磁盘使用:"
df -h | grep -E "^/dev/" | while read line; do
echo " $line"
done
echo ""
echo "3. 用户信息"
echo " 当前用户: $(whoami)"
echo " 登录用户数: $(who | wc -l)"
echo ""
echo "4. 运行时间"
uptime
}
# 调用函数
collect_system_info
示例2:文件备份脚本
bash
#!/bin/bash
# 保存为 backup_script.sh
# 配置
BACKUP_DIR="/tmp/backups"
SOURCE_DIR="$HOME/Documents"
RETENTION_DAYS=7
# 检查并创建备份目录
mkdir -p "$BACKUP_DIR"
# 生成备份文件名
backup_name="backup_$(date +%Y%m%d_%H%M%S).tar.gz"
echo "开始备份..."
echo "源目录: $SOURCE_DIR"
echo "目标: $BACKUP_DIR/$backup_name"
# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
echo "错误:源目录不存在"
exit 1
fi
# 执行备份
tar -czf "$BACKUP_DIR/$backup_name" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")"
if [ $? -eq 0 ]; then
echo "备份成功完成"
echo "备份文件: $BACKUP_DIR/$backup_name"
echo "文件大小: $(du -h "$BACKUP_DIR/$backup_name" | cut -f1)"
else
echo "备份失败"
exit 1
fi
# 清理旧备份
echo "清理 $RETENTION_DAYS 天前的旧备份..."
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "备份任务完成"
示例3:用户管理菜单脚本
bash
#!/bin/bash
# 保存为 user_manager.sh
show_menu() {
echo "=== 用户管理系统 ==="
echo "1. 列出所有用户"
echo "2. 创建新用户"
echo "3. 删除用户"
echo "4. 修改用户密码"
echo "5. 退出"
echo ""
read -p "请选择操作 (1-5): " choice
}
list_users() {
echo "=== 系统用户列表 ==="
echo "用户名 UID 家目录 Shell"
echo "--------------------------------------------"
awk -F: '{printf "%-12s %-8s %-12s %-12s\n", $1, $3, $6, $7}' /etc/passwd | sort -n -k2
}
create_user() {
read -p "请输入新用户名: " username
read -p "请输入用户描述: " description
if id "$username" &>/dev/null; then
echo "错误:用户 $username 已存在"
return 1
fi
sudo useradd -m -c "$description" "$username"
if [ $? -eq 0 ]; then
sudo passwd "$username"
echo "用户 $username 创建成功"
else
echo "用户创建失败"
fi
}
delete_user() {
read -p "请输入要删除的用户名: " username
if ! id "$username" &>/dev/null; then
echo "错误:用户 $username 不存在"
return 1
fi
read -p "是否删除用户的家目录?(y/n): " delete_home
if [ "$delete_home" = "y" ]; then
sudo userdel -r "$username"
else
sudo userdel "$username"
fi
echo "用户 $username 已删除"
}
change_password() {
read -p "请输入用户名: " username
if ! id "$username" &>/dev/null; then
echo "错误:用户 $username 不存在"
return 1
fi
sudo passwd "$username"
}
# 主程序
while true; do
show_menu
case $choice in
1) list_users ;;
2) create_user ;;
3) delete_user ;;
4) change_password ;;
5)
echo "再见!"
exit 0
;;
*)
echo "无效的选择,请重试"
;;
esac
echo ""
read -p "按回车键继续..."
done
第八部分:练习任务
练习1:创建计算器脚本
创建一个脚本 calculator.sh,功能包括:
显示菜单:加法、减法、乘法、除法、退出
根据用户选择执行相应的计算
循环执行直到用户选择退出
练习2:文件批量重命名脚本
创建一个脚本 batch_rename.sh,功能:
将指定目录下的所有 .txt 文件添加前缀
或者修改文件扩展名
显示修改前后的文件名对比
练习3:系统监控脚本
创建一个脚本 system_monitor.sh,功能:
监控CPU使用率,超过阈值时报警
监控内存使用率
监控磁盘空间
将监控结果写入日志文件
第九部分:调试脚本
bash
# 调试方法
# 1. 语法检查
bash -n script.sh # 检查语法错误,不执行
# 2. 详细输出
bash -x script.sh # 显示每个命令的执行过程
# 3. 只显示执行的命令
bash -v script.sh # 显示脚本内容,按行执行
# 4. 组合使用
bash -xv script.sh # 同时显示命令和内容
# 5. 在脚本中启用调试
#!/bin/bash -x # 在shebang中启用
# 或
set -x # 在脚本中启用调试
# 脚本内容...
set +x # 关闭调试
今日总结
我们今天学习了:
Shell脚本的基本概念和执行方法
变量的定义和使用
获取用户输入的多种方式
条件判断的各种形式
循环控制(for、while、until)
函数的定义和调用
实用的脚本示例
重要提醒:
Shell脚本第一行要写 #!/bin/bash
变量赋值等号两边不能有空格
字符串比较用双引号包裹变量
函数使用 local 定义局部变量
脚本要有执行权限才能直接运行
慢慢练习这些脚本,从简单开始,逐渐增加复杂度。Shell脚本是Linux自动化的强大工具。
完成练习后,我们可以继续第八课:定时任务和系统服务管理。
将本文的Word文档下载到电脑
推荐度: