Linux基础教程第七课:Shell脚本编程基础

浏览量:44 次 发布时间:2026-01-18 14:36 作者:明扬工控商城 下载docx

最近更新:Linux基础教程 第15课:Linux内核和驱动管理


好的,我们继续第七课。今天学习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自动化的强大工具。


完成练习后,我们可以继续第八课:定时任务和系统服务管理。


明扬工控商城

推荐阅读:

Linux基础教程 第20课:Linux安全攻防和渗透测试基础

Linux基础教程 第19课:性能调优和容量规划

Linux基础教程 第18课:Linux云计算基础

Linux基础教程 第17课:自动化运维工具

Linux基础教程 第16课:集群和高可用性

Linux基础教程 第15课:Linux内核和驱动管理

热门标签:
Linux基础教程第七课:Shell脚本编程基础.docx

将本文的Word文档下载到电脑

推荐度:

下载

全部评论

请登录
产业新闻-明扬资讯网
科技资讯-明扬资讯网