Shell 脚本的临时文件怎么安全清理?用 mktemp 和 trap 管理临时目录
脚本需要生成中间文件时,把文件固定写到 /tmp/report.txt 虽然方便,但同时运行两个脚本可能互相覆盖;上次运行留下的文件,也可能被误当成这次的结果。
一种更稳妥的做法是:每次运行创建一个独立临时目录,把中间文件放进去,在脚本退出时清理该目录。
每次运行创建独立目录
下面的例子使用 Bash,并适用于常见的 macOS 和 Linux 环境:
#!/usr/bin/env bash
set -euo pipefail
umask 077
workdir="$(mktemp -d "${TMPDIR:-/tmp}/report.XXXXXXXX")"
cleanup() {
rm -rf -- "$workdir"
}
trap cleanup EXIT
printf '%s\n' 'example data' > "$workdir/input.txt"
wc -l < "$workdir/input.txt"
mktemp -d 创建目录并输出路径;模板末尾的 X 由系统替换。不同运行使用不同目录,避免中间文件因固定名称相互覆盖。TMPDIR 已设置且非空时使用它,否则使用 /tmp;给完整路径加引号,可以处理目录名中的空格。
umask 077 让后续创建的普通文件默认不向组用户和其他用户开放权限;临时目录本身由 mktemp -d 创建。临时目录不是不同进程之间的完整安全隔离:同一系统用户运行的程序通常仍能访问自己的文件。
让退出路径也清理
trap cleanup EXIT 在 Bash 退出时执行清理函数。示例在目录创建成功后立即注册清理,再开始生成中间文件。set -e 使简单命令失败时脚本通常会提前退出;例如把最后一行换成 exit 23,退出状态仍是 23,临时目录会被清理。
清理函数只删除本次 mktemp 返回的目录;"$workdir" 的引号不能省略。rm -rf 是递归删除,实际使用时不要把它换成用户输入的任意路径,也不要把目录变量改成共享目录或工作目录。
这个办法也有边界:进程被 SIGKILL 强制结束、系统断电或清理命令自身失败时,不能保证清理完成;删除文件也不等于安全擦除数据。对于敏感内容,还要根据环境选择合适的存储和数据保护方式。
我在本机用带空格的临时父目录验证了示例:多次运行会得到不同目录,正常退出和主动返回错误状态时都会清理,父目录中的无关文件保持不变。
- 点赞
- 收藏
- 关注作者
评论(0)