【问题标题】:Change DNS server by editing /etc/resolv.conf file (using sed) and problem通过编辑 /etc/resolv.conf 文件(使用 sed)和问题更改 DNS 服务器
【发布时间】:2011-10-24 05:58:25
【问题描述】:

我想更改我的 Linux 机器的 DNS 服务器。所以,我要编辑 /etc/resolv.conf 文件。

我使用的命令是 SED。并执行以下操作将 DNS 服务器更改为 192.168.1.5:
#cat /etc/resolv.conf | sed '/nameserver/ c\ nameserver 192.168.1.5' > /etc/resolv.conf

问题是:

当我第一次执行命令时,它会将 resolv.conf 更改为:

domain somedomain
namserver 192.168.1.5

但是当我再次执行它以将 DNS 服务器更改为 192.168.1.4:
#cat /etc/resolv.conf | sed '/nameserver/ c\ nameserver 192.168.1.4' > /etc/resolv.conf

resolv.conf 文件变空

问题:
1. 更改 DNS 服务器的方法是否正确?
2.上述命令中的sed命令有问题吗?

【问题讨论】:

    标签: linux shell sed dns


    【解决方案1】:

    我会想象做如下的事情。使用 sed 将 cat 流操作到另一个文件,然后以某种方式验证这个新文件,例如计算行数,如果新文件有效,则将新文件替换为 /etc/resolv.conf。

    可能是这样的:

    cat /etc/resolv.conf | sed "s/.*nameserver.*/nameserver 192.168.1.5/" > /etc/resolv.conf.sed;
    
    if [ "$(wc -l /etc/resolv.conf.sed)" -eq "0" ]; then
        rm /etc/resolv.conf.sed;
    fi;
    
    if [ -e /etc/resolv.conf.sed ]; then
        mv /etc/resolv.conf.sed /etc/resolv.conf
    fi;
    

    只有最后一行,最好先计算行数,使用 head 将除一行之外的所有行打印到输出文件并使用 tail 打印最后一行,执行 sed 操作并 追加 到输出文件,如下所示:

    I=$(wc -l /etc/resolv.conf | cut -d\/ -f1);
    N=$[I-1];
    head -n$N /etc/resolv.conf > /etc/resolv.conf.sed
    tail -n1 /etc/resolv.conf | sed "s/.*nameserver.*/nameserver 192.168.1.5/" >> /etc/resolv.conf.sed;
    
    if [ "$(wc -l /etc/resolv.conf.sed)" -eq "$I" ]; then
        rm /etc/resolv.conf.sed;
    fi;
    
    if [ -e /etc/resolv.conf.sed ]; then
        mv /etc/resolv.conf.sed /etc/resolv.conf
    fi;
    

    【讨论】:

    • 感谢您提醒我验证部分。将测试它是否有效
    • 你能告诉我如何使用 sed 命令只更改最后一行(如果 resolv.conf 中有两行 nameserver)。有什么语法可以做到吗?
    • 我测试过但无法使用命令:mv,因为/etc 是read-only file system。因此,我将文件 resolv.conf.sed 写入 /tmp 之类的地方,并使用 cat 更改 /etc/resolv.conf(不能删除此文件但可以更改其内容)
    • 要仅更改最后一行,只需将地址范围“$”添加到seds 命令之前会容易得多,例如sed -e '$ s/pattern/replacement',它告诉@ 987654329@ 仅在最后一行运行s 命令。
    【解决方案2】:

    Sed 有文件内版本;这就是我的做法(如果我确定该文件中只定义了一个名称服务器;否则我会做其他事情,但我猜他们不在这个问题范围内)。在示例中,sed 生成一个 resolv.conf_bak 文件以确保安全。

    ~# NAMESERVER=192.168.1.5;
    ~# sed -i_bak "s/\(nameserver\) .*/\1 $NAMESERVER/" /etc/resolv.conf
    

    这是一个更复杂的命令:

    1. 检查是否有名称服务器条目
    2. 如果是这样,用 sed 编辑它
    3. 如果没有创建一个新的

    这是代码:

    ~# grep -q  nameserver /etc/resolv.conf && sed -i_bak "s/\(nameserver\) .*/\1 $NAMESERVER/" /etc/resolv.conf || echo "nameserver $NAMESERVER" >> /etc/resolv.conf
    

    再次,前提是您只使用单个名称服务器条目!

    【讨论】:

      【解决方案3】:

      > 重定向操作的方式,输出文件在任何命令运行之前被截断,这意味着cat 应该看到一个空文件,所以预期的结果是什么。我对您的第一次调用为何有效感到有些困惑。您应该使用临时文件(例如mv resolv.conf resolv.conf~ 并运行sed -e '...' resolv.conf~ > resolv.conf,不需要cat)。或者,如果你有 GNU sed,你可以使用就地编辑选项 (sed -i),同样不需要cat

      【讨论】:

      • 感谢@jw013,我尝试了很多次,第一次总是有效。我对sed and cat 命令有了更清楚的了解。我将使用临时文件
      【解决方案4】:

      使用此代码(未经测试):

      sed 's/nameserver.*/nameserver 192.168.1.5/' /etc/resolf.conf > /etc/resolf.conf.new
      mv /etc/resolf.conf.new /etc/resolf.conf
      

      【讨论】:

      • 这么快的回答。非常感谢。我会测试并报告
      • 我测试了你的命令,不幸的是无法在 /etc 中使用 mv 命令。无论如何感谢您的建议。我明白了:)
      猜你喜欢
      • 2020-03-01
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      相关资源
      最近更新 更多