• 问题: 据用户本人说,Claude Code 在 Windows 上 103 秒删掉了 48,218 个项目文件,起因是脚本走进了 614 个目录联接。
  • 我们发现: 在 macOS 27 上,rm -rf project-link 只删链接;多一个斜杠,rm -rf project-link/ 就删掉了文件夹和里面的四个文件,而且不经过废纸篓。
  • 我们做了什么: Mint 列出一项时不顺着链接走,删之前再核对一次。原来的文件夹变成了链接,或者反过来,Mint 就不删,并告诉你原因。

不加斜杠就不会。在 Mac 上,rm -rf project-link 只删掉符号链接本身,它指向的文件夹原封不动。可要是在末尾多打一个斜杠,rm -rf project-link/ 就把那个文件夹连同里面的四个文件全删了,链接却还留在原地。路径以斜杠结尾时,Python 的 shutil.rmtree 和 Apple 的 FileManager 也会删掉文件夹。这些删除都不经过废纸篓。

下面是我们跑的命令和输出。文末有一行只读命令,能看出你的 Mac 删了文件以后还找不找得回来。

Windows 上发生了什么

2026 年 9 月 21 日,Cybersecurity News 报道,AI 编程 Agent Claude Code 在 103 秒里删掉了 48,218 个正在用的项目文件,时间是美国东部时间晚上 10:10:31 到 10:12:14。这些数字出自用户本人的说法,报道里用的词是“据称”。

当时 Agent 在用一个 Python 脚本清理项目的旧镜像。脚本用 os.walk(..., followlinks=False) 遍历镜像,按理不会顺着链接走进去。可镜像里有 614 个 Windows 目录联接(junction),指回正在用的项目,而 Windows 上的 os.path.islink() 碰到联接会返回 False。遍历就把每个联接都当成了普通文件夹,一个个走了进去。据报道,项目的 Git 对象库也被清空了。

Windows 的情况我们没有去复现。我们想弄清楚的,是链接在 Mac 上会怎样。

测试

10 月 4 日,用的是一台 macOS 27.0.1(26A434)的 Mac。在 zsh 5.9 里,我们进了一个草稿文件夹,建了一个放着四个空文件的文件夹,再建一个指向它的符号链接:

% mkdir my-project
% touch my-project/{app.py,data.csv,notes.md,README.md}
% ln -s my-project project-link

先删链接:

% rm -rf project-link
% ls -F
my-project/
% ls my-project
README.md  app.py  data.csv  notes.md

没了的只有链接,my-project 和里面的文件都还在。重新建好链接,这次在末尾加一个斜杠:

% ln -s my-project project-link
% rm -rf project-link/
% ls -F
project-link@
% ls my-project
ls: my-project: No such file or directory

这回 my-project 和四个文件都不见了,project-link 倒还在,指向一个已经不存在的文件夹。rm 一个字没输出,也没问一句。去掉 -f 结果不变,10 月 6 日重跑一遍,输出一字不差。

一个斜杠为什么能改变结果

斜杠改变了路径指的是什么。按 POSIX 的路径解析规则,路径最后一段是符号链接时,只有后面不跟斜杠,才把它当作链接本身。加了斜杠,系统就会解析这个链接,project-link/ 指的便是 my-project。rm 删的是交给它的东西,先删里面的文件,在 macOS 上随后连文件夹一起删掉。

在 Mac 上,遍历本身没出问题。10 月 6 日,os.walk('.', followlinks=False) 把 project-link 列成了文件夹,但没有走进去。决定结果的,是交给删除操作的那个路径。

Python 和 Swift

用 Apple 自带的 /usr/bin/python3(3.9.6,来自开发者工具),对重新建好的文件夹:

% /usr/bin/python3 -c "import shutil; shutil.rmtree('project-link')"
Traceback (most recent call last):
  ...
OSError: Cannot call rmtree on a symbolic link
% /usr/bin/python3 -c "import shutil; shutil.rmtree('project-link/')"
% ls my-project
ls: my-project: No such file or directory

不带斜杠,rmtree 拒绝执行;带上斜杠,它一声不吭就删了 my-project。Homebrew 的 Python 3.14.5 第二条也删掉了文件夹,只是第一条的报错文字不同,是 OSError: [Errno None] None: 'project-link'。

接着用一个小 Swift 程序试了 Foundation。给 FileManager.default.removeItem(atPath:) 传 project-link,它只删链接;传 project-link/,它删掉文件夹和里面的文件,链接留了下来。

不进废纸篓,没有“放回原处”

rm、shutil.rmtree 和 removeItem 都是当场删除。文件不经过废纸篓,所以没有“放回原处”,APFS 也没有反删除。数据恢复软件是有的,我们没有测过。能稳妥找回文件的,是备份。

测试用的 Mac 没有备份

10 月 4 日,这台测试机:

% tmutil listlocalsnapshots /
Snapshots for disk /:
% tmutil destinationinfo
tmutil: No destinations configured.

没有本地快照,没有备份磁盘,到 10 月 6 日还是这样。

按 Apple 的本地快照说明,时间机器(Time Machine)也会在 Mac 本机上留备份。它大约每小时给启动磁盘存一个快照,每个保留 24 小时;另外留一个最近一次成功备份的快照,直到需要空间为止。这台 Mac 没设备份磁盘,这些快照一个都没有。快照是什么、为什么会算进“系统数据”,可以看我们的 Time Machine 快照指南。

如果你让 Agent 在 Mac 上跑命令

能用终端的 Agent,和人一样敲得出 rm -rf。在这次测试里,删掉一个链接还是一整个文件夹,只差一个字符。Agent 写路径时有多常在末尾带斜杠,我们不知道。你自己能管住的是备份,设一次就行,路径是“系统设置”>“通用”>“时间机器”>“添加备份磁盘”。最好在把终端交给 Agent 之前就设好。

查查你的 Mac

下面这行只读,不要密码。整行粘进“终端”:

d=$(tmutil destinationinfo 2>&1); n=$(tmutil listlocalsnapshots / 2>/dev/null | grep -c 'com.apple'); l=$(tmutil latestbackup 2>/dev/null | sed 's#.*/##'); echo "Backup disk: $(echo "$d" | grep -q 'No destinations' && echo none || echo "$d" | awk -F' *: ' '/^Name/{print $2; exit}')"; echo "Local snapshots: $n"; echo "Latest backup: ${l:-none}"

我们这台的输出:

Backup disk: none
Local snapshots: 0
Latest backup: none

zsh 5.9 和 macOS 自带的 bash 3.2 里都跑过。设了 Time Machine 磁盘的话,第一行应该是磁盘名,最后一行是最近一次备份,不过这种输出我们自己还没见过。中间的数字是 tmutil listlocalsnapshots / 列出的快照个数,单独跑这条命令就能看到快照名字。

Mint 怎么做

Mint 是一款 Mac 存储应用,它也删文件。列出一项时,它记下的是这一项本身,不顺着链接走;真要删之前,再核对一次。原来是文件夹的地方变成了链接,或者反过来,Mint 就不删,并告诉你原因。你在 Yours 里选的文件会移到废纸篓,用 Mint 的撤销能放回去;Safe to clean 里的缓存和构建产物则直接删除。Mint 不做备份,代替不了 Time Machine。

常见问题

不带斜杠,rm -rf 会删掉文件夹吗? 我们跑的几次都没有,不带斜杠时只删了链接。

普通文件夹加不加斜杠有区别吗? 没有。rm -rf my-project 和 rm -rf my-project/ 都会删掉真正的文件夹。只有路径最后一段是链接时,斜杠才有影响。

删文件夹之前,怎么看里面有哪些链接? 跑一下 find my-project -type l,它会列出里面所有的符号链接,什么都不改。在我们的草稿文件夹里,find . -type l 输出的是 ./project-link。

有本地快照的话,文件能找回来吗? Apple 说,备份磁盘没连上的时候,Time Machine 也能从本地快照恢复文件。恢复我们没试过,而测试机上本来就没有快照。

这是 macOS 的 bug 吗? 路径末尾带斜杠时去解析链接,是 POSIX 规定的。最后连文件夹本身一起删掉,这一步在不同系统上可能不一样,在 macOS 上是删了。