同一个替换脚本在 Linux 上正常,同事的 Mac 上执行报 sed: 1: "/data/conf.yml": invalid command code d,配置文件没有被修改。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

sed -i.bak 's/^port:.*/port: 8080/' /data/conf.yml
diff /data/conf.yml.bak /data/conf.yml

BSD sed 的 -i 必须带一个备份后缀参数,不写就把后面的文件名当成后缀,剩下的路径被当成脚本。GNU sed 允许 -i 后面直接跟文件。这一点先确认清楚,后面就不用反复试。

「sed -i 跨平台」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。

改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

具体做法是,统一用 sed -i.bak 两端都能跑;或者判断系统后分别传参;替换前先备份 替换后用 diff 确认只改了目标行;在两个平台各跑一次 检查文件内容和退出码。

改完照着核一遍,macOS 和 Linux 上都不报错,diff 只显示 port 那一行变化。

作者 9823189