Codex 总在 /tmp 留下文件?一步步配置自动清理
Codex 做完任务后,运行中创建的辅助脚本、下载文件和测试日志还留在 /tmp。次数多了,不仅占空间,也很难分清哪些文件可以删除。
解决办法是给每个任务分配独立临时目录,明确告诉 Codex 何时清理,再让创建目录的代码负责自动删除。对于本地 Codex CLI,还可以用启动脚本在前台命令退出后清理整个会话的临时目录。
本文面向有基本终端操作经验的 Linux 和 WSL 用户,处理的是为你的任务创建的临时文件。Codex 自身的运行时文件、持久状态和工具缓存可能有不同的生命周期。
选择清理方法
| 方法 | 清理时机 | 适用场景 |
|---|---|---|
AGENTS.md 规则 |
Codex 完成任务时 | 项目或用户的长期指令 |
Bash EXIT trap |
所属 shell 退出时 | 一次 shell 操作,包括命令失败 |
Python TemporaryDirectory |
退出 with 代码块时 |
Python 脚本,包括普通异常 |
| CLI 启动脚本 | 本地前台 Codex 命令退出时 | 会话级补充清理 |
先加入指令规则,再给临时脚本加上自动清理。 如果还想在 CLI 会话结束时清理,可以继续配置启动脚本。指令可以约束智能体的行为,但不能保证进程崩溃、被 SIGKILL 终止或关机后还能执行删除。
第 1 步:先检查文件,不急着删除
在 Codex 实际执行命令的 Linux 环境中运行:
codex --version
du -sh /tmp
if [ -d /tmp/codex-work ]; then
du -sh /tmp/codex-work
find /tmp/codex-work -mindepth 1 -maxdepth 1 -type d -print
fi
这一步只是查看现状。/tmp 其他位置的文件不一定属于 Codex 任务,不能确认归属的文件先保留。下面的步骤会让新建文件有明确的归属和清理范围。
本文参数已对照本机 Codex CLI 0.162.1 和官方 CLI 文档核对。如果你的版本不同,先查看 codex --help。
第 2 步:在 AGENTS.md 中加入长期规则
如果只希望规则作用于当前项目,在仓库根目录打开 AGENTS.md:
nano AGENTS.md
如果希望所有项目默认遵守,在 Codex 用户目录打开指令文件:
mkdir -p "${CODEX_HOME:-$HOME/.codex}"
nano "${CODEX_HOME:-$HOME/.codex}/AGENTS.md"
把下面的段落追加到现有文件,保留其他指令:
## Temporary files
- Create a unique directory for each task under /tmp/codex-work/.
- If TMPDIR points to a dedicated Codex session directory, create task
directories inside that directory instead.
- Put temporary scripts, downloads, logs, and intermediate files there.
- Record the exact task directory you created.
- Save final deliverables in the workspace before cleanup.
- Wait for processes using task files to finish before deleting them.
- Use a Bash EXIT trap or Python TemporaryDirectory when practical.
- Before finishing, delete only your task directory, verify it is gone,
and report any cleanup failure.
- Never clear all of /tmp, delete other tasks' files, or remove persistent
Codex state and caches as part of task cleanup.
- The session directory supplied through TMPDIR belongs to the launcher;
delete your task subdirectory, not the launcher's session directory.
这段规则要求每个任务有独立目录,记录路径,先保存结果、等待相关进程结束,再清理并确认目录消失。如果启动脚本提供会话级 $TMPDIR,任务目录就放在其中;智能体只清理自己的子目录,把会话目录留给启动脚本。
Codex 在启动时读取全局和项目指令。同层级的 AGENTS.override.md 优先于 AGENTS.md,更深层的项目指令可以覆盖前面的规则。修改后重启会话,并确认实际生效的文件。官方 AGENTS.md 文档
在新会话里输入:
Summarize the temporary-file rules you loaded. For this task, record the
temporary directory, save deliverables in the workspace, then delete your
task directory and verify it is gone.
这会把清理列为任务完成的一部分。下面两步把删除直接放进可执行代码,使普通命令失败时也能清理。
第 3 步:用 Bash EXIT trap 自动清理
在项目根目录运行这个完整示例:
bash <<'BASH'
set -euo pipefail
task_base="${TMPDIR:-/tmp/codex-work}"
mkdir -p "$task_base"
task_tmp=$(mktemp -d "$task_base/task-XXXXXXXX")
trap 'rm -rf -- "$task_tmp"' EXIT
printf 'Task directory: %s\n' "$task_tmp"
mkdir -p artifacts
printf 'temporary input\n' > "$task_tmp/input.txt"
tr '[:lower:]' '[:upper:]' < "$task_tmp/input.txt" > "$task_tmp/result.txt"
cp -- "$task_tmp/result.txt" artifacts/cleanup-result.txt
cat artifacts/cleanup-result.txt
BASH
输出会包含本次任务的独立目录,以及:
TEMPORARY INPUT
结果保存在 artifacts/cleanup-result.txt,临时目录在这次 Bash 进程退出时删除。命令失败、set -e 使 shell 退出时,EXIT trap 也会执行。
目录创建、处理和清理必须放在同一个 shell 脚本里。一次工具调用注册的 trap 不能负责另一次独立 shell 的清理。跨多次调用的工作,需要由智能体记录任务目录,最后明确删除。
引号和 -- 让删除命令指向 mktemp 返回的精确目录,不要改成匹配整个 /tmp 的通配符。这个示例使用前台命令;如果启动了子进程,先等它们结束,再让负责清理的 shell 退出。按第 6 步检查清理结果,不要假设删除总能成功。
第 4 步:用 Python TemporaryDirectory 自动清理
把下面代码保存为 cleanup_demo.py,也可以下载完整示例:
#!/usr/bin/env python3
import os
import shutil
from pathlib import Path
from tempfile import TemporaryDirectory
base = Path(os.environ.get("TMPDIR", "/tmp/codex-work"))
base.mkdir(parents=True, exist_ok=True)
output = Path("artifacts/cleanup-result-python.txt")
output.parent.mkdir(parents=True, exist_ok=True)
with TemporaryDirectory(prefix="task-", dir=base) as directory:
task_tmp = Path(directory)
print(f"Task directory: {task_tmp}")
intermediate = task_tmp / "result.txt"
intermediate.write_text("temporary input\n".upper(), encoding="utf-8")
shutil.copyfile(intermediate, output)
print(f"Temporary directory exists: {task_tmp.exists()}")
print(f"Deliverable exists: {output.exists()}")
使用 Python 3 运行,无需第三方依赖:
python3 cleanup_demo.py
最后两行应为:
Temporary directory exists: False
Deliverable exists: True
Python 会在退出上下文时删除目录,包括普通异常导致的退出。单独使用 mkdtemp() 需要自己清理,详见 Python tempfile 文档。
临时文件全部写入这个目录,最终结果在离开代码块之前复制出去。先关闭文件句柄,并等待子进程结束。进程被突然终止时,上下文清理也可能无法执行。
第 5 步:给本地 Codex CLI 加上退出清理
还可以加一层启动脚本:创建独立会话目录,设置 TMPDIR,等待前台 CLI 命令结束,再删除目录。CLI 执行失败时,脚本会保留它的退出码。
先在项目中创建 scripts/ 目录,再把下面内容保存为 scripts/codex-clean。也可以下载启动脚本:
#!/usr/bin/env bash
set -euo pipefail
command -v codex >/dev/null 2>&1 || {
printf 'codex is not on PATH\n' >&2
exit 127
}
run_root=/tmp/codex-work
mkdir -p "$run_root"
run_tmp=$(mktemp -d "$run_root/session-XXXXXXXX")
readonly run_tmp
cleanup() {
run_status=$?
trap - EXIT
if rm -rf -- "$run_tmp"; then
printf 'Cleaned session directory: %s\n' "$run_tmp" >&2
else
printf 'Cleanup failed: %s\n' "$run_tmp" >&2
if [ "$run_status" -eq 0 ]; then
run_status=1
fi
fi
exit "$run_status"
}
trap cleanup EXIT
export TMPDIR="$run_tmp"
printf 'Session directory: %s\n' "$run_tmp" >&2
codex --no-daemon --sandbox workspace-write \
--add-dir "$run_tmp" \
-c "shell_environment_policy.set.TMPDIR=\"$run_tmp\"" \
"$@"
然后执行:
mkdir -p scripts
# Save the launcher above as scripts/codex-clean before running:
chmod +x scripts/codex-clean
./scripts/codex-clean
进入会话后,让 Codex 在 $TMPDIR 中创建任务子目录,并遵守第 2 步的规则。使用完后退出 CLI,启动脚本才会清理会话目录。交互会话还开着时,一条回复完成不会触发启动脚本的 trap。
如果只执行一个非交互任务:
./scripts/codex-clean exec \
'Use a unique task directory inside TMPDIR for scratch files. Save a short cleanup test report as artifacts/codex-cleanup-report.txt, then remove your task directory and verify it is gone.'
请在你信任的仓库中运行。如果 CLI 停在仓库检查阶段,先解决这个前置问题,再判断清理行为。
启动脚本为会话目录增加写入权限,明确设置工具 shell 的 TMPDIR,并用 --no-daemon 执行本地前台运行。参数见 CLI 文档,环境变量过滤见配置文档。
TMPDIR 是工具约定,不是文件系统隔离。命令如果写死了 /tmp/example,仍可能在会话目录外创建文件;启动脚本只删除自己的目录。远程会话、脱离终端的任务和共享后台服务需要按实际生命周期清理。退出前先结束或停止使用临时文件的进程,需要跨会话恢复的数据应保存在工作区。
第 6 步:验证目录已删除,结果仍然存在
启动脚本会输出类似下面的路径:
Session directory: /tmp/codex-work/session-Ab12Cd34
Cleaned session directory: /tmp/codex-work/session-Ab12Cd34
检查本次运行实际打印的路径。下面的命令让你粘贴路径,避免猜测目录名:
bash <<'BASH'
read -r -p 'Paste the session directory printed by the launcher: ' checked_tmp < /dev/tty
if [ -e "$checked_tmp" ]; then
printf 'Still exists: %s\n' "$checked_tmp"
else
printf 'Removed: %s\n' "$checked_tmp"
fi
test -f artifacts/codex-cleanup-report.txt
BASH
执行前面的非交互示例后,应看到 Removed: ...,结果文件检查也应成功。再查看报告内容。模型回复里的一句“已清理”,不如文件系统检查能直接证明结果。如果检查 Bash 示例,则使用它打印的任务路径,以及 artifacts/cleanup-result.txt。
也可以只列出还存在的会话目录,不执行删除:
find /tmp/codex-work -mindepth 1 -maxdepth 1 -type d -name 'session-*' -print
其他目录可能属于仍在运行的会话。父目录不为空,不代表你这次运行清理失败。
第 7 步:常见问题与处理方法
Codex 仍然直接向 /tmp 写文件
让它通过实际工具 shell 输出 $TMPDIR,并在 mktemp -d "$TMPDIR/task-XXXXXXXX" 或 TemporaryDirectory(dir=...) 中明确指定目录。一些工具会忽略 TMPDIR。如果环境策略配置了允许列表,确认其中包含 TMPDIR,不要关闭整套策略。环境变量策略文档
AGENTS.md 的规则没有生效
在目标项目里重新启动 Codex,检查同层级的 AGENTS.override.md。如果设置了 CODEX_HOME,修改该目录内的指令文件。让 Codex 概述当前清理规则。指令发现规则
Permission denied 或启动参数不支持
确认当前用户可以在 /tmp/codex-work 下创建目录,并查看 codex --help。共享服务器上,如果父目录属于其他用户,换成自己拥有且可写的任务目录,同时修改规则和启动脚本。--add-dir 为 workspace-write 模式增加写入目录,但组织策略仍可能限制权限。保留沙箱;如果旧版 CLI 不支持 --no-daemon,先更新 CLI,或使用前面的脚本级方法。
崩溃后目录仍然存在
指令和 EXIT trap 都无法在 SIGKILL 或断电之后执行。确认精确目录属于已停止的运行、没有需要保存的结果后,只删除这个目录。不要按文件年龄直接安排定时删除,长时间运行的任务也可能使用旧文件。自动处理崩溃残留,需要按调度系统设计归属和存活状态检查。
清理成功,但磁盘空间还是没恢复
可能有其他进程仍打开着已经删除的文件。可以继续阅读 Linux 删除文件后磁盘仍满的排查教程。继续删除无关临时文件不能定位这个问题。
总结
在 AGENTS.md 中写清临时文件规则,为每个任务创建独立目录,并在清理前保存结果。Bash trap 和 Python 上下文管理器可以在正常完成和普通失败时自动删除临时文件。本地 CLI 启动脚本还能在命令退出时补充清理;最后检查精确目录是否消失,并把持久结果留在工作区。
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/codex-tmp-auto-clean.html
- 版权声明:本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。