You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下Bash脚本执行出现意外无限循环问题求助

问题:Bash脚本合并文本文件时出现无限循环

我尝试运行一段Bash脚本,用于合并文件夹及子文件夹中所有文本文件的内容并输出到一个文本文件,脚本内容如下:

#!/bin/bash

find . -type f -name '*.txt' -exec cat {} + >> output.txt

但该脚本出现了无限循环。

我的测试目录结构为:~/desktop/Dir0/Dir1/Dir2
我创建了两个文本文件:

  • 在~/desktop/Dir0/Dir1执行:touch text1.txt && echo "Hello" >> text1.txt
  • 在~/desktop/Dir0/Dir1/Dir2执行:touch text2.txt && echo "World" >> text2.txt

随后我在Dir0目录内运行了该脚本。脚本始终无法结束,运行cat output.txt可见文件中无限重复Hello\nWorld\nHello\nWorld\nHello\nWorld...内容。

我已尝试的排查步骤:

  • 在Mint虚拟机中运行同一脚本,可正常工作。
  • 将Bash从3.2版本升级至5.1.16,问题仍存在。
  • 查阅资料并进行测试。

请问有人知道可能是什么原因导致的吗?


原因分析与解决办法

核心原因

脚本执行时,>> output.txt会在当前目录(Dir0)创建output.txt文件,而find . -name '*.txt'会递归查找所有.txt文件,包括刚创建的output.txt。当find收集到这个新文件后,会再次执行cat把它的内容追加到自身,导致无限循环:

  1. 初始find找到text1.txt和text2.txt,执行cat将内容写入output.txt
  2. output.txt被创建后,后续的find迭代会把它也纳入目标文件列表
  3. cat output.txt会把现有内容(Hello\nWorld)再次追加到output.txt,文件不断变大,循环往复

解决办法

有几种方式可以避免这个问题:

  1. 将输出文件放在查找范围之外
    比如把output.txt放到上级目录:

    find . -type f -name '*.txt' -exec cat {} + >> ../output.txt
    
  2. 在find命令中排除输出文件
    使用! -name参数排除output.txt:

    find . -type f -name '*.txt' ! -name 'output.txt' -exec cat {} + >> output.txt
    
  3. 先收集所有文件再执行cat
    用变量存储找到的文件列表,再一次性合并,避免find过程中捕获新创建的文件:

    #!/bin/bash
    files=$(find . -type f -name '*.txt')
    cat $files >> output.txt
    

    注意:如果文件名包含空格,这种方式可能有问题,更稳妥的写法是用数组:

    #!/bin/bash
    mapfile -t files < <(find . -type f -name '*.txt')
    cat "${files[@]}" >> output.txt
    

另外,你提到在Mint虚拟机中脚本正常工作,可能是因为该环境下find的实现或文件系统特性导致它没有重复扫描到新创建的output.txt,但这属于特殊情况,标准场景下必须考虑排除输出文件或移出查找范围。

内容的提问来源于stack exchange,提问作者code_resources

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:24:47