PAYATHON 2026

find 配合 sha256sum 时如何排除哈希输出文件?

数据阿明

在 find 中加入 ! -name 'hashedoutput.sha256',就能排除输出文件。Shell 会在启动 find 前处理 > 重定向,创建输出文件或清空已有文件,因此 find 扫描目录时会看到它。

修改函数

gen_sha256sum () {
    find "$1" -maxdepth 1 -type f \
        ! -name 'hashedoutput.sha256' \
        -exec sha256sum {} + > "$1/hashedoutput.sha256"
}

调用时传入需要处理的目录:

gen_sha256sum /path/to/files

各条件的作用是:

  • -maxdepth 1:只检查指定目录及其直接子项,不进入子目录。
  • -type f:只处理普通文件。
  • ! -name 'hashedoutput.sha256':排除名为 hashedoutput.sha256 的文件。
  • -exec sha256sum {} +:将匹配的文件分批作为参数交给 sha256sum 计算。

函数只处理一层目录,按固定文件名排除即可满足需求。

为什么输出文件会成为输入

虽然重定向写在原命令末尾,Shell 也会在 find 执行前打开输出文件。处理顺序是:

  1. 打开 $1/hashedoutput.sha256,如果文件不存在就创建,存在则截断为空文件。
  2. 启动 find,并将其标准输出连接到该文件。
  3. find 扫描 $1,发现 hashedoutput.sha256 也符合 -type f,便把它传给 sha256sum。

因此,即使第一次运行前没有这个文件,也可能出现同样的问题。提前删除输出文件也无济于事,因为重定向会在扫描前重新创建它。

使用时需要注意什么

不要依赖文件遍历顺序来避开输出文件。如果文件在写入时又被读取,算出的哈希值无法代表最终生成的完整清单,应明确将它排除。

把 > 换成 >> 也不能解决问题。追加重定向同样会提前打开或创建输出文件,还会保留旧内容,使清单不断累积。

保留原来的 -exec ... {} + 写法即可,无需把文件名拼接成字符串再交给 Shell 执行。这种传参方式可以正确处理包含空格等字符的文件名。

题目标题提到了 openssl,但给出的函数调用的是 sha256sum。问题来自 Shell 重定向和 find 的筛选条件,无需改用 openssl。

备注:内容仅供参考。