sed无法实现永久修改,如何让命令写入hosts文件?
解决sed命令无法永久写入hosts文件的问题
问题根源
你原命令加-i失效主要有两个原因:
- 双引号下Shell会先展开
$(cat tmp_script),如果tmp_script里包含/、&、\这类sed特殊字符,会直接破坏替换表达式的语法。 - 不同系统的sed对
-i参数的语法要求不同(GNU sed直接用-i,BSD sed需要-i '')。
修复后的命令
适配GNU/Linux系统(带备份)
sudo sed -i.bak -E "s|( )[^#]*|\1$(sed 's/[|&]/\\&/g' tmp_script) |" hosts
适配BSD/macOS系统(带备份)
sudo sed -i '' -E "s|( )[^#]*|\1$(sed 's/[|&]/\\&/g' tmp_script) |" hosts
关键修改说明
- 用
|代替/作为sed替换的分隔符,避免tmp_script中的/干扰语法。 sed 's/[|&]/\\&/g' tmp_script:转义tmp_script里的&和|,这两个字符在sed中有特殊含义,转义后会被当作普通文本处理。-i.bak(GNU)或-i ''(BSD):-i参数实现原地修改,.bak会生成原文件的备份(hosts.bak),防止操作失误丢失数据。
备选方案(更稳定处理复杂内容)
如果tmp_script内容特别复杂,用awk替代sed会更可靠:
sudo awk -v script="$(cat tmp_script)" '{if ($0 !~ /^#/) {sub(/ [^#]*/, " " script " ")} print}' hosts > hosts.tmp && sudo mv hosts.tmp hosts
这个逻辑是:遍历hosts文件,对非注释行(不以#开头)执行替换,输出到临时文件后覆盖原文件,避免直接修改时的异常。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

