rsync -avn、find … -print 和 git clean -nd 会原样打印破坏性版本将要做的事,而它们与真实命令之间只差一个参数。习惯每次都一样:先用"给我看看"模式跑一遍,读完清单,再把参数去掉。例外是 rm——它没有这种模式,所以替代做法很重要。
1. rsync:-n 显示将会复制什么
$ clai 显示 rsync 会复制什么,但先别复制→ rsync -avn src/ backup/sending incremental file listapp.pyutil.pylogs/logs/app.logsent 159 bytes received 29 bytes 376.00 bytes/sectotal size is 8 speedup is 0.04 (DRY RUN)
最后那两个词 (DRY RUN) 是输出里唯一的差别。文件清单和真实执行完全一致——去掉 -n,复制的就是这些。
2. rsync --delete:会咬人的组合
$ clai 显示 rsync 会在目标目录里删掉什么→ rsync -avn --delete src/ backup/sending incremental file listdeleting old-report.csvdeleting obsolete.py./notes.txtutil.pylogs/old.log
deleting 这几行就是值得为 -n 费这道手续的全部理由。不加它,这两个文件会悄无声息地消失——已验证:同样的命令去掉 -n 后打印了同样两行,并且真的删除了。
3. find:先 -print,后 -delete
$ clai 显示超过 30 天的日志,但不要删→ find src -name '*.log' -mtime +30 -printsrc/logs/old.log
find 从左往右求值,所以放在末尾的 -print 显示的正是 -delete 会拿到的清单。千万不要调换顺序:-delete -name '*.log' 会先删掉整棵树,然后才去过滤。
4. git clean:-n 打印将要删除的东西
$ clai 显示 git clean 会删掉哪些未跟踪文件→ git clean -ndWould remove backup/Would remove src/notes.txtWould remove tmpdir/
-n 是检查,-d 表示连目录一起。不先跑 -nd 就直接 git clean -fd,是丢掉一个忘了 add 的文件最快的方式。
5. sed:预览就是不带 -i 的 sed
$ clai 显示 conf.ini 替换后的样子,但不要改文件→ sed 's/old/new/' conf.inihost=newport=80
不带 -i 时,sed 把结果打印到终端而不碰文件——这就是它自带的空跑模式。已验证:之后 cat conf.ini 显示的仍然是 host=old。
6. 真要写回文件时,留一份副本
$ clai 在 conf.ini 里做替换,但保留备份→ sed -i.bak 's/old/new/' conf.ini
旁边会出现内容为原文的 conf.ini.bak。在 macOS 上这个后缀是必填的,哪怕是空的(-i '')——从 Linux 搬过去的脚本正是栽在这个细节上。
Gotchas
rm没有空跑模式。 替代办法是用ls跑同样的通配符:ls -1 src/logs/*.log显示的正是rm src/logs/*.log会带走的东西。echo rm …也行,它把完整命令打印出来而不执行。-n在不同命令里含义不同。 在 rsync 里是空跑,在grep -n里是行号,在sort -n里是按数字排序。不要盲目迁移习惯:find 把检查叫-print,git 叫--dry-run。- 检查和执行之间只能差一个参数。 如果你顺手还改了路径、通配符或参数顺序,那检查的就是另一条命令。请从已经敲好的那行里删掉
-n,而不是重新敲一遍。
Related questions
包管理器有空跑模式吗? 有:apt-get -s install 包名 会显示计划而不安装,dnf 用 --assumeno,docker 有 docker system prune --dry-run。
怎么知道脚本会做什么? bash -n script.sh 只检查语法、不执行;bash -x script.sh 会在执行每条命令前打印它——注意,它是真的会执行。
rsync --delete 能撤销吗? 不能。防护只有两种:事先用 -n,或者用 --backup --backup-dir=… 把该删的文件挪到别处而不是删掉。
See also
CliAI 会把破坏性命令标成 CAUTION 或 DANGER,并先给出它的空跑写法。一行安装。