Shell 脚本编程学习总结(基础 + 变量 + 条件 + 流程控制 + 函数数组)

一、Shell 基础概述

1. Shell 发展历史

  1. 1964 年:贝尔实验室、MIT、通用电气联合研发 Multics 大型多用户系统

  2. 1970 年:丹尼斯・里奇、汤普逊启动 UNICS 项目,后续演进为 Unix

  3. 1973 年:使用 C 语言重写 Unix,实现跨机型移植

  4. 1979 年:首个标准 Bourne Shell(sh) 正式发布

  5. 后续衍生:csh/tcsh/ksh/bash/zshLinux 默认 Shell 为 bash

2. 查看系统 Shell

bash 复制代码
# 查看系统所有支持的Shell
cat /etc/shells

# 查看当前登录默认Shell
echo $SHELL

3. Shell 两大核心定位

  1. 命令解释器 用户操作 → Shell 解析命令 → 传递内核 → 调度硬件; Shell 是用户与 Linux 内核的中间代理,不属于内核,是独立应用程序。

  2. 解释型脚本语言

  • 无需编译,直接运行源码,开发部署极简

  • 内置两千 + Linux 命令,搭配三剑客可做系统自动化运维

  • 对比编译型语言:脚本灵活跨平台;编译型速度快、保密性强


二、Shell 脚本书写规范与执行

1. 标准书写规范

  1. 脚本后缀建议:.sh,见名知意

  2. 首行固定声明解析器:#!/bin/bash

  3. 注释规则

  • 单行注释:# 开头

  • 多行注释语法:

bash 复制代码
:<<'EOF'
这里是多行注释第一行
这里是多行注释第二行
EOF
  1. 可配置 ~/.vimrc 新建.sh 自动生成头部版权注释

2. 常用输出命令

echo 命令
  • -n:不换行输出

  • -e:启用转义字符,可设置字体颜色、高亮、下划线

printf 命令
  • 格式化输出,必须手动加 \n 换行

  • 支持格式符:%s字符串、%d整型、%f浮点

  • 可设置字符宽度、左右对齐、保留小数位数

3. 一行多命令连接符

|------|---------------|
| 符号 | 功能说明 |
| ; | 顺序执行,前后命令互不影响 |
| & | &前命令成功才执行后命令 |
| || | 前命令失败才执行后命令 |
| | | 管道,左输出作为右输入 |

4. 脚本四种执行方式

  1. 绝对路径 / 相对路径 :需 x 执行权限,子 Shell 运行,不影响当前终端

  2. bash 脚本名:无需执行权限,子 Shell 运行

  3. source 脚本名:当前 Shell 运行,变量 / 目录切换永久生效

  4. . 脚本名:等同于 source

核心区别:子 Shell 执行不影响当前环境;source/. 在当前 Shell 执行,环境变更永久生效。

5. 退出状态码

  1. 范围:0~2550 成功,非 0 失败

  2. 查看状态码:echo $?

  3. 脚本自定义退出:exit 数字

  4. 函数返回状态码:return 数字

  5. 常见状态码:

  • 0:命令执行成功

  • 1:未知错误

  • 2:命令使用错误

  • 126:命令不可执行

  • 127:命令未找到

  • 130:Ctrl+C 强制终止


三、Shell 变量全解

1. 变量命名与赋值规则

  • 命名:只能字母、数字、下划线,不能数字开头

  • 赋值:变量=值等号两边严禁空格

  • 值含空格必须用单 / 双引号包裹

  • Shell 是弱类型动态语言,所有变量均以字符串存储

2. 变量定义方式

  1. 临时变量:命令行直接定义,退出终端失效

  2. 命令赋值:\\var=date``` 或 var=$(date)`

  3. 交互式赋值:read -p "提示信息" 变量1 变量2

  4. 永久环境变量

    1. 用户级:~/.bashrc~/.bash_profile

    2. 系统级:/etc/profile/etc/bashrc/etc/profile.d/*.sh

3. 特殊位置参数变量

|--------|----------------|
| 变量 | 含义 |
| 0 | 脚本自身名称 | | 19 | 第 1 到第 9 个位置参数 | | {10} | 10 个以上参数必须加大括号 |
| \* | 所有参数视为一个整体 | | @ | 所有参数独立分开 |
| # | 传入参数总个数 | | \\$$ | 当前脚本进程 PID | | ? | 上一条命令退出状态码 |

4. 引号与特殊符号区别

  1. 单引号 '':所有符号原样输出,无任何解析

  2. 双引号 "" :解析$、`````、\,其余字符原样

  3. 反引号 `````:将内容当作系统命令执行

  4. 反斜线 \:转义特殊字符,取消特殊含义

5. 变量运算

  1. 整数运算:$(( ))$[]letexpr

  2. 小数运算:仅 bcawk 支持

  3. 字符串处理语法

    bash 复制代码
    ${#var}          # 获取字符串长度
    ${var:start:len} # 字符串截取
    ${var/old/new}   # 替换第一个匹配
    ${var//old/new}  # 全局替换
    ${var#*.}         # 从左最短删除
    ${var##*.}        # 从左最长删除
    ${var%.*}         # 从右最短删除
    ${var%%.*}        # 从右最长删除

6. 变量作用域

  1. 局部变量
  • 普通变量:当前脚本 / 终端生效

  • 函数局部:local 变量 仅函数内部有效

  1. 全局环境变量
  • 定义:export 变量=值

  • 特性:当前 Shell 及所有子进程共享

7. 变量默认值扩展语法

|--------------|------------------|--------|
| 语法 | 作用 | 是否修改变量 |
| {var:-word} | 变量为空返回 word,原值不变 | 否 | | {var:=word} | 变量为空赋值为 word | 是 |
| {var:+word} | 变量非空返回 word | 否 | | {var:?word} | 变量为空抛出错误并退出 | 否 |

8. 经典案例

  • 两数加减乘除、求余

  • 1~100 求和、奇数和、偶数和

  • 批量批量重命名文件

  • 自动清理 7 天前过期备份


四、条件测试

1. 四种测试语法

  1. test 条件表达式

  2. [ 条件表达式 ]中括号左右必须有空格

  3. [[ 条件表达式 ]] 支持正则、逻辑更强大

  4. (( 整数表达式 )) 仅用于整数判断

2. 三大测试类型

文件测试

-e存在、-d目录、-f普通文件、-L软链接、-r可读、-w可写、-x可执行、-nt文件更新、-ot文件更旧

字符串测试

-z空字符串、-n非空字符串、=相等、!=不等

整数测试
  • []/test 使用:-eq -ne -gt -ge -lt -le

  • [[]]/(()) 直接使用:> < >= <= == !=

3. 逻辑运算符

|-----------------|-------|-------|-------|
| 使用场景 | 与(并且) | 或(或者) | 非(取反) |
| test / \[\] | -a | -o | ! |
| \[] / (()) | & | &|| | ! |

4. 正则匹配

[[ 字符串 =~ ^[0-9]+$ ]] 可判断是否为纯数字、字母等格式

5. 实战案例

  • 统计系统登录用户数

  • 判断文件行数阈值

  • 检测 SSH 服务是否运行

  • Ping 探测主机存活

  • 键盘输入两数自动计算


五、流程控制

1. if 条件判断

  • 单分支:满足条件执行

  • 双分支:满足执行 A,否则执行 B

  • 多分支:if...elif...elif...else...fi

经典场景:root 权限校验、求最大值、内存告警、闰年判断、成绩评级

2. case 多分支匹配

适合固定值、区间匹配,替代多 elif,语法简洁

bash 复制代码
case 变量 in
值1) 命令 ;;
值2) 命令 ;;
*) 默认命令 ;;
esac

常用于:菜单选择、星期判断、参数匹配

3. 四大循环

for 循环
  1. 列表循环:for i in {1..10}

  2. 命令结果循环:for i in $(ls)

  3. C 语言风格:for((i=1;i<=10;i++))

while 循环

条件为真持续执行,支持死循环 while true / while : 常用于:逐行读取文件、交互式猜数字

until 循环

条件不成立执行,成立终止,与 while 逻辑相反

select 循环

快速生成交互式数字菜单,可自定义 PS3 提示符

4. 循环控制关键字

  • break n:跳出当前 / 多层循环

  • continue n:跳过本次 / 多层本次循环

  • exit n:直接退出整个脚本


六、Shell 函数

1. 函数优势

代码复用、模块化、结构清晰、易维护、可移植

2. 函数定义语法

bash 复制代码
# 写法1
function 函数名 {
  命令
}

# 写法2
函数名() {
  命令
}

3. 函数调用与传参

  • 同文件直接调用:函数名 参数1 参数2

  • 跨文件调用:source 函数库.sh 加载后调用

4. 返回值与作用域

  1. 返回值
  • return 只能返回 0-255 数字

  • echo 可返回字符串、运算结果

  1. 变量作用域
  • 无 local 默认全局变量

  • 函数内 local 变量 仅内部生效

5. 递归函数

函数调用自身,常用于:阶乘计算、递归遍历目录(模拟 tree)


七、Shell 数组

1. 数组分类

  • 普通索引数组:下标为数字

  • 关联数组:下标为字符串,需声明 declare -A arr

2. 数组定义方式

bash 复制代码
# 直接赋值
arr=(a b c d)
# 下标单独赋值
arr[0]=1;arr[1]=2
# 命令结果赋值
arr=$(ls /etc)

3. 数组常用操作

bash 复制代码
${arr[*]}     # 获取所有元素
${!arr[*]}    # 获取所有下标
${#arr[*]}    # 获取数组长度
unset arr[n]  # 删除指定元素
unset arr     # 删除整个数组

4. 数组遍历

  1. 下标循环遍历

  2. 直接元素遍历

相关推荐
吃好睡好便好1 小时前
矩阵的左乘和右乘
人工智能·学习·线性代数·算法·matlab·矩阵
我命由我123451 小时前
SEO 与 GEO 极简理解
java·linux·运维·开发语言·学习·算法·运维开发
楼兰公子1 小时前
RK3588 Linux驱动开发大纲
linux·驱动开发
段一凡-华北理工大学2 小时前
工业领域的Hadoop架构学习~系列文章04:YARN资源调度架构
人工智能·hadoop·学习·架构·系统架构·高炉炼铁·高炉炼铁智能化
爱上好庆祝2 小时前
学习JS第十二天
学习
!沧海@一粟!2 小时前
Linux高并发内核优化
linux·运维·oracle
perfect123126452 小时前
轻量运维工具fastdp v6版本
linux·运维
Upsy-Daisy2 小时前
IOTA 学习笔记(一):IOTA 是什么?从区块链到 Tangle
笔记·学习·区块链
魔法阵维护师2 小时前
从零开发游戏需要学习的c#模块,第三十三章(暂停菜单)
学习·游戏·c#