尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Bash 中的 shopt -s globstar:递归 Glob 模式详解 - 教程

Bash 中的 shopt -s globstar:递归 Glob 模式详解 - 教程
📅 发布时间:2026/6/20 0:31:38

引言

在 Unix-like 系统中,Bash(Bourne-Again SHell)作为最流行的命令行 shell,已成为开发者和系统管理员的必备工具。Bash 不仅仅是一个简单的命令解释器,它还提供了强大的文件路径扩展机制,即“globbing”(通配符匹配)。Globbing 允许用户使用如 *、? 等模式来匹配文件和目录,而无需编写复杂的正则表达式或调用外部工具。这使得文件操作变得高效而直观。

然而,传统的 globbing 模式有一个显著的局限性:它无法递归遍历子目录。例如,使用 ls *.txt 只能匹配当前目录下的 .txt 文件,而忽略嵌套在子目录中的文件。这在处理复杂目录结构时常常令人沮丧,尤其是项目目录或日志文件夹中文件层层嵌套的情况下。幸运的是,Bash 4.0 版本引入了一个名为“globstar”的 shell 选项,通过 shopt -s globstar 启用,它让双星号 ** 成为递归匹配的利器。 这个选项将 globbing 的能力扩展到整个目录树,让用户能够轻松实现如 ls **/*.txt 这样的递归文件查找。

本文将详细介绍 globstar 的原理、启用方法、基本与高级用法、实际应用场景,以及与传统工具如 find 的比较,确保你能立即上手。

globstar 的历史与启用方法

globstar 并非 Bash 的原创功能,它受到了其他 shell 如 Zsh 和 Ksh93 的启发。这些 shell 早在 Bash 4.0(2009 年发布)之前就已支持递归 globbing。 Bash 的引入 globstar 旨在增强其与这些现代 shell 的兼容性,同时保持向后兼容性。默认情况下,globstar 是禁用的,这避免了潜在的意外行为——因为在旧版 Bash 中,** 仅被视为单个 * 的变体,仅匹配当前目录。

要启用 globstar,只需在 Bash 会话中执行以下命令:

shopt -s globstar

这里的 shopt 是 Bash 的内置命令,用于管理 shell 选项(shell options)。-s 参数表示“set”(设置),globstar 是选项名称。执行后,你可以通过 shopt globstar 检查状态,它会输出 globstar on。 如果想临时禁用,可以使用 shopt -u globstar(-u 为 unset),或在脚本开头添加 shopt -u globstar 以确保兼容旧环境。

对于永久启用,你可以将 shopt -s globstar 添加到 ~/.bashrc 文件中。这样,每次启动 Bash 时都会自动加载。需要注意的是,globstar 要求 Bash 版本至少 4.0。如果你使用的是较旧的系统(如某些嵌入式设备),可能需要升级 Bash 或回退到 find 等工具。

在脚本中,检查 globstar 是否启用也很重要。可以使用条件语句:

if shopt -q globstar; thenecho "globstar 已启用"# 执行递归 glob 代码
elseecho "globstar 未启用,请使用 find 命令"# 备选方案
fi

shopt -q(quiet 模式)会静默执行,并根据选项状态设置退出码(0 表示 on,非 0 表示 off)。这种检查确保脚本在不同环境中鲁棒运行。

基本用法:从简单递归查找开始

启用 globstar 后,** 的行为发生质变。它不再是简单的通配符,而是递归匹配器:** 会匹配当前目录下的所有文件和零或更多层级的目录及子目录。 最经典的示例就是用户提到的 ls **/*.txt,它会递归查找当前目录树中所有 .txt 文件。

假设你的目录结构如下:

project/
├── README.txt
├── src/
│   ├── main.py
│   └── utils/
│       └── helper.txt
└── docs/└── guide.txt

不启用 globstar 时,ls *.txt 只输出 README.txt。但启用后,ls **/*.txt 会输出:

README.txt
src/utils/helper.txt
docs/guide.txt

这大大简化了文件搜索,无需 find . -name "*.txt" 的冗长语法。

另一个基本示例:列出所有子目录。使用 ls **/ 会递归列出所有目录路径,如 src/ utils/ docs/ 等。 注意末尾的 / 确保只匹配目录(详见高级用法)。

在 for 循环中,globstar 同样强大:

for file in **/*.log; doecho "处理日志: $file"# 例如:tail -f "$file"
done

这会遍历所有 .log 文件,进行批量处理,如日志分析或备份。 相比 for file in $(find . -name "*.log"); do ... done,globstar 版本更简洁,且避免了命令替换的潜在问题(如文件名中空格)。

globstar 还支持数组赋值:

txt_files=(**/*.txt)
echo "找到 ${#txt_files[@]} 个 txt 文件"
for file in "${txt_files[@]}"; doecho "$file"
done

${#txt_files[@]} 返回数组长度,便于统计文件数。这种方式比管道 ls **/*.txt | wc -l 更高效,因为它不创建子 shell。

高级用法:组合模式与排除技巧

globstar 的真正魅力在于与其它 glob 字符的组合,以及细粒度控制。Bash 的 glob 包括 *(匹配任意字符序列,不包括 /)、?(单个字符)、[ ](字符类)和 { }(大括号扩展)。启用 globstar 后,这些可以与 ** 无缝结合。

首先,区分 ** 和 **/:

  • **:匹配文件和目录。例如,echo ** 会列出所有文件和目录路径,包括嵌套的。
  • **/:后跟 / 时,只匹配目录和子目录。例如,printf "%s\n" **/ 会输出所有目录路径,如 src/ docs/ src/utils/。 这类似于 find . -type d,但更简洁。

组合示例:查找特定子目录下的文件,如 **/{src,docs}/*.py。这会递归匹配 src 或 docs 目录下的所有 .py 文件。 大括号 {src,docs} 是 Bash 的扩展功能,与 globstar 完美协作。

字符类示例:**/.[^.]* 匹配所有隐藏文件(以 . 开头,但不以 .. 开头)。[!.]* 排除以 . 开头的文件。 完整命令:ls **/.[!.]* 递归列出非隐藏隐藏文件?不,[!.]* 匹配不以 . 开头的文件。修正:要匹配隐藏文件,ls **/.[!.]* 实际匹配以 . 开头但第二个字符不是 . 的文件,如 .git 但排除 ..。

排除模式是高级用法中的亮点。虽然 Bash glob 不原生支持否定,但可以通过 !(扩展 glob)结合。启用 shopt -s extglob 后,可以使用 !(pattern) 排除。 示例:ls **/*.txt !**/backup/*.txt 查找所有 .txt 但排除 backup 目录下的。

另一个高级技巧:深度限制。虽然 globstar 默认无深度限制,但结合 {1,3}(大括号范围)模拟:**/{1,3}/*.txt 但这不精确,因为 ** 已递归。实际中,对于深度控制,仍推荐 find。但对于模式如 **/*.{jpg,png},它高效匹配图像文件。

在脚本中,globstar 可用于条件匹配:

case "$1" in**/*.zip) unzip "$1" ;;**/*.tar.gz) tar -xzf "$1" ;;*) echo "不支持的文件类型" ;;
esac

这根据递归路径自动解压。

与 find 命令的比较:何时选择 globstar

globstar 常常被视为 find 的轻量替代品,但两者各有优劣。find 是外部命令,支持复杂过滤(如 -mtime 时间戳、-size 大小),并可执行动作(如 -exec)。globstar 则纯 shell 内部,速度更快,无需 fork 子进程。

比较示例:递归查找 .txt 文件。

  • globstar:wc -l **/*.txt 统计所有 txt 行数。
  • find:find . -name "*.txt" -exec wc -l {} + 类似,但更慢。

基准测试显示,在大型目录中,globstar 可快 2-5 倍,因为它避免了外部调用。 但 find 支持 -prune 排除目录,如 find . -path "./backup" -prune -o -name "*.txt" -print,而 globstar 需要 extglob 辅助。

何时用 globstar?简单模式匹配、脚本内循环。

何时用 find?复杂查询、权限检查。

最佳实践:小项目用 globstar,大型系统用 find。

实际应用场景:从日常到脚本编写

globstar 在实际工作中无处不在。以下是几个实用场景。

1. 文件备份与同步

备份所有源代码:tar -cf backup.tar **/{*.py,*.sh}。这打包当前目录下所有 Python 和 shell 脚本,递归子目录。 同步到远程:rsync -av **/*.html user@server:/web/ 高效传输网站文件。

2. 批量文件处理

清理旧日志:rm **/*.log.(old|bak) 删除以 .old 或 .bak 结尾的日志。结合日期:但 globstar 无时间过滤,可与 find 混合:find . -name "**/*.log" -mtime +7 -delete。

图像处理:假设有 ImageMagick,mogrify -resize 800x **/*.{jpg,png} 批量缩放所有图像。

3. 开发工作流

在 Git 项目中,搜索变更:git diff **/*.py 但 git 不直接支持;实际用 grep -r "pattern" **/*.py 递归 grep。 测试覆盖:pytest **/test_*.py 运行所有测试文件。

4. 系统管理

监控服务:ps aux | grep **/proc/[0-9]*/status 但 procfs 特殊;更实用:kill **/*.pid 清理进程 ID 文件。

在 Docker 或 CI/CD 中,globstar 简化 artifact 收集:如 GitLab CI 的 artifacts: paths: - "**/*.jar" 递归打包 JAR 文件。

5. 脚本示例:智能文件整理器

以下是一个完整脚本,利用 globstar 整理下载文件夹:

#!/bin/bash
shopt -s globstar  # 启用 globstar
shopt -s extglob   # 启用扩展 glob
downloads="$HOME/Downloads"
cd "$downloads" || exit 1
# 移动图像
mv **/*.{jpg,jpeg,png,gif} Pictures/ 2>/dev/null
# 移动文档
mv **/*.{pdf,docx,txt} Documents/ 2>/dev/null
# 移动压缩包
mv **/*.{zip,rar,tar.gz} Archives/ 2>/dev/null
echo "整理完成!"

这个脚本会递归扫描 Downloads,分类移动文件。 你可以扩展它,添加日志或确认提示。

总结

shopt -s globstar 是 Bash 中一个低调却强大的功能,它将简单的 ** 转变为递归魔力,极大简化了文件操作。从 ls **/*.txt 的日常查找,到复杂脚本的批量处理,globstar 让 Bash 更接近现代 shell 的优雅。在编写自动化脚本时,记住这一工具,它将给你节省大量时间。

相关新闻

  • Docker存储驱动OverLay2介绍
  • 2025年哈尔滨ISO环境体系认证渠道权威推荐榜单:辽宁ISO20000质量管理体系认证/沈阳ISO20000质量管理体系/大连ISO三体系认证源头公司精选
  • 2025年贵州推拿正骨培训机构权威推荐榜单:小儿按摩培训/小儿推拿培训/穴位敷贴培训源头机构精选

最新新闻

  • PIC17CXX外部SRAM接口设计:时序计算、硬件连接与调试实战
  • 2026深度实测!主流AI编程助手横向对比,开发者真实选型指南
  • 无锡本地买宠避坑指南,附几家宠物店参考 - 园友3800037
  • 南充翻译盖章:2026最新办理流程 - 资讯速览
  • 2026年6月最新格拉苏蒂中国官方售后电话网点地址及客户服务热线 - 亨得利官方服务中心
  • 果速修2026年品牌发展全景:从上海首店到全国200+门店,官方热线400-811-2953 - 博客万

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号