touch无法修改文件创建时间(birth time),仅能设置atime和mtime,而ctime随元数据变更自动更新且不可手动设定;-d参数支持自然语言设时间,-r默认同步复制atime和mtime。

touch 不能修改文件的“创建时间”(birth time / crtime),Linux 文件系统(如 ext4、XFS)虽支持该字段,但 touch 命令本身不提供设置它的接口。它只能可靠地操作 atime(访问时间)和 mtime(修改时间),而 ctime(状态变更时间)会随任何元数据改动自动更新,无法手动设定。
为什么 touch -m 不等于“只改修改时间”?
执行 touch -m file 确实只显式更新 mtime,但 ctime 必然同步变化——因为文件的 inode 元数据被修改了。这不是 bug,是内核强制行为。你用 stat file 查看时会发现 Change: 行时间总等于操作时刻,哪怕加了 -m。
-
atime可能不变(取决于挂载选项,如noatime) -
mtime按指令更新 -
ctime总是当前真实时间,不可绕过
如何把文件时间设成“昨天下午3点”?
用 -d 或 -t 参数,推荐 -d:它支持自然语言,容错强,且跨时区安全。
touch -d "yesterday 15:00" filetouch -d "2026-05-21 15:00:00" file- 若必须用
-t,格式严格为YYYYMMDDhhmm[.ss]:touch -t 202605211500 file - 注意:非 root 用户无法将时间设为未来太远(如 2200 年),部分内核会拒绝超出合理范围的值
复制另一个文件的时间戳,但只复制 mtime?
touch -r ref_file target_file 默认同时复制 atime 和 mtime。若只想继承 mtime,得拆成两步:
- 先用
stat -c "%y" ref_file提取 ref_file 的 mtime(ISO 格式) - 再用
touch -d "$(stat -c "%y" ref_file)" target_file - 或者更稳妥:用
touch -m -d "$(stat -c "%y" ref_file)" target_file显式限定只动 mtime - 别依赖
touch -r加-m组合——它仍会同步复制 atime
想批量重置一堆 .log 文件的 mtime 为今天零点?
直接写 shell 循环最稳,避免通配符意外匹配目录或隐藏文件:
for f in *.log; do [ -f "$f" ] && touch -m -d "today 00:00" "$f" done
关键点:
-
[ -f "$f" ]过滤掉非普通文件(比如误匹配到目录) - 引号包裹
"$f"防空格路径出错 -
touch -m确保不碰 atime(尤其在启用了relatime的系统上) - 如果文件名含换行符等极端情况,需改用
find+-exec,但日常日志批量处理没必要
touch 的真正限制不在语法,而在 Linux 时间模型本身:它没有“创建时间 API”。所有声称“修改创建时间”的工具(如 debugfs 直接写 ext4 inode)都属危险操作,极易损坏文件系统,且不跨文件系统通用。实际工作中,应接受 ctime 是唯一可查的“最后元数据变更时间”,并用 mtime 表达业务意义上的“最后修改”。


















