linux辅助知识(Shell 脚本编程)

发布于:2025-07-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

目录

一、什么是 Shell 脚本?

二、基础入门:脚本创建与执行

1. 脚本文件格式

2. 执行脚本的 3 种方式

三、核心语法:变量与输入输出

1. 变量定义与使用

2. 字符串处理

3. 特殊变量(脚本参数与状态)

4. 输入输出重定向

四、控制结构:条件与循环

1. 条件判断(if-else)

2. 循环(for/while)

(1)for 循环

(2)while 循环(条件为真时持续执行)

3. case 语句(多分支判断)

五、函数:代码复用

1. 函数定义与调用

2. 函数返回值

六、常用工具:文本处理与系统操作

1. 文本处理

2. 系统操作

七、错误处理与调试

1. 错误处理

2.脚本调试

八、实战示例:自动备份脚本

九、最佳实践

十、应用场景


Shell 脚本编程是 Linux/Unix 系统中自动化任务、批量处理和系统管理的核心技术。它通过将一系列命令按逻辑组织成文本文件,实现自动化执行,极大提升了工作效率。以下从基础到进阶详细介绍 Shell 脚本编程:

一、什么是 Shell 脚本?

  • Shell:是用户与操作系统内核交互的命令行解释器(如 bash、zsh、sh 等),负责解析并执行用户输入的命令。
  • Shell 脚本:将一系列 Shell 命令按逻辑顺序写入文本文件,通过解释器批量执行,实现自动化任务(如日志分析、备份、部署等)。

最常用的 Shell 是 bash(Bourne Again SHell),本文以 bash 为例讲解。

二、基础入门:脚本创建与执行

1. 脚本文件格式

Shell 脚本文件以 .sh 为扩展名(非强制),开头必须指定解释器(shebang 行):

#!/bin/bash
# 这是注释(# 开头的行为注释)
echo "Hello, Shell Script!"  # 输出内容
  • #!/bin/bash:指定脚本由 bash 解释器执行(必须放在第一行)。
2. 执行脚本的 3 种方式
  • 方式 1(推荐):赋予执行权限后直接运行

chmod +x script.sh  # 赋予执行权限
./script.sh         # 运行脚本(需在脚本所在目录)
  • 方式 2:通过 bash 解释器直接调用

    bash script.sh  # 无需执行权限,直接用 bash 运行

  • 方式 3:通过 source 或 . 执行(会在当前 Shell 环境中运行,变量可保留)

    source script.sh  # 等价于 . script.sh

三、核心语法:变量与输入输出

1. 变量定义与使用

定义变量:变量名 = 值(等号两边无空格

name="Alice"  # 字符串变量
age=25        # 数值变量

使用变量:通过 $变量名 或 ${变量名} 引用({} 用于区分边界)

echo "Name: $name"       # 输出:Name: Alice
echo "Age: ${age}岁"     # 输出:Age: 25岁({} 避免歧义)

只读变量:用 readonly 定义,无法修改

readonly pi=3.14
pi=3.1415  # 报错:pi: readonly variable

删除变量:用 unset(只读变量不可删除)

unset name  # 删除 name 变量
2. 字符串处理

单引号 vs 双引号

    单引号 '':字符串原样输出,不解析变量和转义字符

echo 'Name: $name'  # 输出:Name: $name

    双引号 "":解析变量和转义字符(如 \n 换行)

echo "Name: $name"  # 输出:Name: Alice

字符串长度${#变量名}

echo "Length of name: ${#name}"  # 输出:5("Alice" 长度为 5)

字符串截取${变量名:起始位置:长度}

str="hello world"
echo ${str:6:5}  # 输出:world(从索引 6 开始,取 5 个字符)
3. 特殊变量(脚本参数与状态)
变量 含义
$0 脚本文件名
$1~$n 脚本的第 1~n 个参数($1 是第一个参数)
$# 参数的总个数
$* 所有参数的集合(作为单个字符串)
$@ 所有参数的集合(作为独立字符串)
$? 上一个命令的退出状态(0 表示成功)
$$ 当前脚本的进程 ID(PID)

示例:script.sh 内容

#!/bin/bash
echo "脚本名:$0"
echo "第一个参数:$1"
echo "参数总数:$#"
echo "所有参数:$@"

执行:./script.sh apple banana,输出:

脚本名:./script.sh
第一个参数:apple
参数总数:2
所有参数:apple banana
4. 输入输出重定向

输出重定向:将命令结果写入文件(覆盖 / 追加)

echo "Hello" > output.txt  # 覆盖写入 output.txt
echo "World" >> output.txt # 追加写入 output.txt

输入重定向:从文件读取输入(替代键盘输入)

wc -l < input.txt  # 统计 input.txt 的行数(等价于 wc -l input.txt)

管道 |:将前一个命令的输出作为后一个命令的输入

ps aux | grep "python"  # 查找包含 "python" 的进程

四、控制结构:条件与循环

1. 条件判断(if-else)

语法:

if 条件; then
  # 条件成立时执行
elif 条件; then
  # 其他条件成立时执行
else
  # 所有条件不成立时执行
fi

条件表达式:用 [ ](test 命令的简写)或 [[ ]](bash 扩展,支持更多特性),注意括号前后必须有空格

常见判断类型:

数值比较-eq(等于)、-ne(不等于)、-gt(大于)、-lt(小于)等

a=10
b=20
if [ $a -lt $b ]; then
  echo "$a < $b"
fi

字符串比较=(等于)、!=(不等于)、-z(空字符串)、-n(非空字符串)

str="test"
if [ -n "$str" ]; then  # 字符串非空
  echo "str is not empty"
fi

文件测试-f(普通文件)、-d(目录)、-r(可读)、-w(可写)、-x(可执行)

file="script.sh"
if [ -f "$file" ] && [ -x "$file" ]; then  # 是文件且可执行
  echo "$file is an executable file"
fi
2. 循环(for/while)
(1)for 循环

语法 1:遍历列表

for fruit in apple banana orange; do
  echo "Fruit: $fruit"
done

语法 2:类 C 风格(循环范围)

for ((i=1; i<=5; i++)); do
  echo "Count: $i"
done

语法 3:遍历目录文件

for file in ./test/*; do  # 遍历 test 目录下的所有文件
  if [ -f "$file" ]; then
    echo "File: $file"
  fi
done
(2)while 循环(条件为真时持续执行)
count=1
while [ $count -le 3 ]; do
  echo "Count: $count"
  count=$((count + 1))  # 变量自增(算术运算用 $(( )))
done

无限循环(配合 break 退出):

while true; do
  read -p "输入 q 退出:" input
  if [ "$input" = "q" ]; then
    break  # 退出循环
  fi
done
3. case 语句(多分支判断)

适用于变量匹配多个固定值的场景:

read -p "输入分数(A/B/C):" grade
case $grade in
  A) echo "优秀" ;;
  B) echo "良好" ;;
  C) echo "及格" ;;
  *) echo "无效输入" ;;  # * 匹配所有未列出的值
esac

五、函数:代码复用

1. 函数定义与调用
# 定义函数
greet() {
  echo "Hello, $1!"  # $1 是函数的第一个参数
}

# 调用函数(传递参数)
greet "Bob"  # 输出:Hello, Bob!
2. 函数返回值

通过 return 返回状态码(0~255,0 表示成功)

add() {
  return $(( $1 + $2 ))  # 返回两数之和(状态码范围限制,不适合大数值)
}
add 3 5
echo "结果:$?"  # 输出:8($? 获取上一个命令的返回值)

通过 echo 输出结果(适合返回字符串或大数值)

multiply() {
  echo $(( $1 * $2 ))  # 输出乘积
}
result=$(multiply 4 5)  # 用 $() 捕获输出
echo "结果:$result"  # 输出:20

六、常用工具:文本处理与系统操作

Shell 脚本的强大之处在于结合各类命令工具,常见场景:

1. 文本处理

grep:查找匹配的行(支持正则表达式)

grep "error" app.log  # 从 app.log 中查找包含 "error" 的行

awk:按列处理文本(数据提取、统计)

awk '{print $1, $3}' data.txt  # 打印 data.txt 的第 1 列和第 3 列

sed:文本替换(批量修改内容)

sed -i 's/old/new/g' file.txt  # 将 file.txt 中所有 "old" 替换为 "new"
2. 系统操作

find:查找文件

find /home -name "*.txt"  # 在 /home 下查找所有 .txt 文件

tar:压缩 / 解压文件

tar -czf backup.tar.gz ./data  # 压缩 data 目录为 backup.tar.gz

df/du:查看磁盘空间

df -h  # 查看磁盘使用情况(人类可读格式)

七、错误处理与调试

1. 错误处理
  • set -e:脚本中任何命令失败(返回非 0 状态)时立即退出

#!/bin/bash
set -e  # 开启错误退出
command1  # 若失败,脚本直接退出
command2  # 不会执行

trap:捕获信号(如脚本退出时执行清理操作)

cleanup() {
  echo "脚本退出,执行清理..."
  # 清理临时文件等操作
}
trap cleanup EXIT  # 脚本退出时调用 cleanup 函数
2.脚本调试
  • 执行时加 -x 参数:打印执行的每一条命令(方便定位问题)
bash -x script.sh  # 调试模式运行脚本

八、实战示例:自动备份脚本

#!/bin/bash
# 功能:每天备份指定目录到 /backup,并保留最近 7 天的备份

# 配置参数
SOURCE_DIR="/home/user/documents"  # 要备份的目录
BACKUP_DIR="/backup"               # 备份存储目录
DATE=$(date +%Y%m%d)               # 当前日期(如 20231001)
BACKUP_FILE="$BACKUP_DIR/doc_backup_$DATE.tar.gz"

# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
  echo "错误:源目录 $SOURCE_DIR 不存在!"
  exit 1  # 非 0 状态表示失败
fi

# 创建备份目录(若不存在)
mkdir -p "$BACKUP_DIR"

# 执行备份
echo "开始备份 $SOURCE_DIR 到 $BACKUP_FILE..."
tar -czf "$BACKUP_FILE" "$SOURCE_DIR"

# 检查备份是否成功
if [ $? -eq 0 ]; then
  echo "备份成功!"
else
  echo "备份失败!"
  exit 1
fi

# 删除 7 天前的备份
echo "清理 7 天前的备份..."
find "$BACKUP_DIR" -name "doc_backup_*.tar.gz" -mtime +7 -delete

echo "操作完成!"

九、最佳实践

  1. 注释清晰:关键步骤添加注释,说明用途和逻辑。
  2. 变量复用:将路径、配置等定义为变量,方便维护。
  3. 检查边界:执行命令前检查文件 / 目录是否存在、权限是否足够。
  4. 避免硬编码:通过参数或配置文件传递可变值。
  5. 测试脚本:先用 bash -n script.sh 检查语法错误,再逐步调试。

十、应用场景

  • 系统监控:定时检查磁盘、内存、进程状态。
  • 日志分析:批量处理日志文件,提取关键信息。
  • 自动化部署:一键部署代码、配置环境。
  • 批量处理:批量重命名文件、转换格式等。


网站公告

今日签到

点亮在社区的每一天
去签到