在 CentOS 6.8 (sed 4.2.1) 上執行:
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux
導致 /etc/sysconfig/selinux(指向 ../selinux/config 的軟鏈接)變為普通文件,鏈接關係斷裂,SELinux 配置實際未生效。
sed -i 默認採用重命名替換策略:
結果:原鏈接被替換為獨立副本,源文件未被修改。
| 參數 | 機制 | 優點 | 缺點 | 推薦度 |
|---|---|---|---|---|
--follow-symlinks | 識別鏈接並直接修改目標文件 | 保持鏈接關係、原子性、速度快、安全 | 較新版本 sed 才支持 | ⭐⭐⭐⭐⭐ |
-c / --copy | 複製模式替換重命名 | 不破壞硬/軟鏈接 | 非原子操作、較慢、罕見場景才需用 | ⭐⭐ |
| 無參數 (默認) | 重命名替換 | 標準行為 | 破壞鏈接 | ❌ |
# 準備測試環境 echo "test" > test ln -s test test-link # ❌ 破壞鏈接 sed -i "s/test//g" test-link # test-link 變為普通文件 # ✅ 方案 1:--follow-symlinks (推薦) sed -i --follow-symlinks '/test/d' test-link # 鏈接關係保持,目標文件 test 內容被清空 # ✅ 方案 2:-c / --copy sed -i -c '/test/d' test-link # 鏈接關係保持,但操作非原子
--follow-symlinks 選項,默認行為不破壞鏈接(舊版本邏輯不同)。--follow-symlinks。以下常見配置文件均為軟鏈接,直接 sed -i 會導致服務啟動失敗:
/etc/sysconfig/selinux → ../selinux/config/etc/rc.local → /etc/rc.d/rc.local/etc/rc.d/rc*.d/ 下的啟動腳本鏈接# 安全修改鏈接文件通用模板
sed -i --follow-symlinks 's/OLD/NEW/g' /path/to/symlink
# 批量處理腳本中建議檢測版本
if sed --version 2>&1 | grep -q '4.2'; then
SED_INPLACE="sed -i --follow-symlinks"
else
SED_INPLACE="sed -i"
fi
$SED_INPLACE '...' file