命令`ls **/*.exe`遗漏本目录下文件?Bash的globstar配置了解一下

某天,我需要快速统计服务器上所有.exe文件(包括当前目录和子目录),于是输入了命令:

bash 复制代码
ls -l ./**/*.exe

预期结果应包含当前目录下的.exe文件(./*.exe)和所有子目录中的.exe文件(./**/*.exe)。然而实际操作中,发现当前目录的.exe文件未被列出,只有子目录中的文件被匹配。这一现象与直觉相悖,引发了我的探索。


问题定位:为什么**/*.exe不包含当前目录?

  1. 初步排查

    • 检查命令语法:ls的路径参数确实包含./**/*.exe,理论上应覆盖所有层级。
    • 验证文件存在性:确认当前目录确实存在.exe文件,且权限正常。
  2. 发现关键线索

    执行以下命令单独测试通配符:

    bash 复制代码
    echo ./*.exe        # 正常输出当前目录的.exe文件
    echo ./**/*.exe     # 仅输出子目录中的.exe文件

    结果显示,**/*.exe未匹配当前目录的文件,而是仅递归子目录。

  3. 理解**的行为

    • 在默认Bash配置中,**通配符的行为与常见工具(如find)不同:它仅匹配目录层级,而非同时匹配文件和目录。
    • 例如,**/*.exe会匹配subdir/file.exe,但不会匹配./file.exe,因为当前目录的"层级深度"为0,而**要求至少一层子目录。

解决方案:启用globstar选项

通过搜索和AI对话,得知Bash的globstar选项可修改**的行为:

bash 复制代码
shopt -s globstar  # 启用globstar
ls -l **/*.exe     # 此时会包含当前目录和所有子目录的.exe文件

技术解析

  • shopt命令 :用于控制Bash的Shell选项(Shell Options),-s表示启用选项。
  • globstar的作用 :
    • 启用后,**会匹配零层或多层目录,即包括当前目录。
    • 例如:**/*.exe将匹配./file.exe(当前目录)、./subdir/file.exe、./subdir/subsubdir/file.exe等。

验证操作

  • 检查globstar状态:

    bash 复制代码
    shopt globstar    # 输出"globstar on"或"globstar off"
  • 永久启用(写入Bash配置文件):

    bash 复制代码
    echo 'shopt -s globstar' >> ~/.bashrc  # 对所有新会话生效

问题复盘:为什么最初命令未生效?

最初的命令组合./*.exe ./**/*.exe看似全面,实则存在冗余:

  • 未启用globstar时 :**/*.exe仅匹配子目录,需显式添加./*.exe才能覆盖当前目录。
  • 启用globstar后 :**/*.exe已包含当前目录,无需额外指定./*.exe。

因此,更简洁的解决方案是:

bash 复制代码
shopt -s globstar && ls -l **/*.exe

知识总结与拓展

  1. 学到的知识点

    • globstar选项 :控制**通配符的递归行为,需手动启用。
    • shopt命令 :管理Bash的Shell选项,如调试模式(extdebug)、历史扩展(histverify)等。
    • 路径匹配逻辑:理解通配符的层级匹配规则,避免误用。
  2. 实用技巧

    • 快速检查选项状态 :shopt <选项名>。

    • 跨Shell兼容性 :Zsh默认启用globstar,而Bash需手动配置。

    • 常见错误 :

      bash 复制代码
      # 未启用globstar时,**/*.txt可能匹配不到文件
      ls **/*.txt          # 错误:返回"**/*.txt"字面量
      shopt -s globstar    # 修正:先启用再执行
  3. 扩展应用场景

    • 批量操作文件:

      bash 复制代码
      # 删除所有临时文件(当前目录及子目录)
      rm **/*.tmp
    • 结合find命令:若需更复杂的过滤(如按修改时间),find仍是更好的选择。


结语:从问题到知识的转化

这次经历揭示了Shell工具中看似简单的功能(如通配符)背后隐藏的配置细节。通过实践、验证和原理分析,不仅解决了眼前的问题,更深化了对Bash行为的理解。在Linux运维中,此类"小配置大作用"的案例屡见不鲜,唯有保持好奇与探索,才能持续精进。


附录:5个Shell调试小技巧

  1. 使用set -x实时显示命令执行过程。
  2. 通过echo测试通配符扩展结果。
  3. 检查命令的man手册(如man bash搜索globstar)。
  4. 对比不同Shell(如Bash vs Zsh)的行为差异。
  5. 将常用配置写入~/.bashrc以避免重复操作。
相关推荐
澜山奕秋7 小时前
RHCSA
linux·运维·服务器
Web极客码8 小时前
告别流式截断:我用客户端中间件解决长文本 API 跨国 SSE 断连与数据自愈
linux·agent 图
cnnews8 小时前
Chromebox3安装Ubuntu后内存化与最小化 eMMC 写入优化
linux·运维·ubuntu
flytalei9 小时前
Ubuntu 24.04 单节点 K3s 部署实践:从环境评估到故障排查与验收
linux·运维·ubuntu
Starry-sky(jing)9 小时前
Hermes Agent 部署后怎么升级?v0.21.7 Linux 源代码版实测
linux·人工智能·ai agent·版本升级·hermes agent
水饺编程9 小时前
第2章:Linux 基础,clear 命令
linux·c语言·汇编
GeW10 小时前
新质生产力路线图Linux和数据库自主可控实践指南
linux
yunwei3710 小时前
eBPF 教程:BPF 迭代器用于内核数据导出
linux·后端·性能优化
别动我齐刘海10 小时前
实时控制学习2
linux·c++·人工智能·学习·算法
行者-全栈开发11 小时前
【容器/虚拟化】CVE-2026-53359:Linux KVM Januscape 虚拟机逃逸漏洞修复指南(潜伏16年的云安全噩梦)
linux·运维·服务器·多租户隔离·cve-2026-53359·kvm虚拟机逃逸·shadow mmu