【问题标题】:Append line to /etc/hosts file with shell script使用 shell 脚本将行附加到 /etc/hosts 文件
【发布时间】:2013-10-20 18:42:53
【问题描述】:

我有一个新的 Ubuntu 12.04 VPS。我正在尝试编写一个安装脚本来完成整个 LAMP 安装。我遇到问题的地方是在/etc/hosts 文件中添加一行。我当前的主机文件如下所示:

127.0.0.1       localhost Venus

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

我希望它看起来像这样:

127.0.0.1       localhost Venus
192.241.xx.xx  venus.example.com venus

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

我使用 append (\a) 命令尝试了各种sed 命令。出于某种原因,Ubuntu 要么只是在终端中回显 hosts 文件的内容,要么什么都不做。如何使用 bash 脚本将第二行正确地注入文件中?

【问题讨论】:

标签: linux bash shell ubuntu sed


【解决方案1】:

确保使用sed-i 选项。

-i[SUFFIX], --in-place[=SUFFIX]
  edit files in place (makes backup if extension supplied)

sed -i "2i192.241.xx.xx  venus.example.com venus" /etc/hosts

否则,

echo "192.241.xx.xx  venus.example.com venus" >> /etc/hosts

将在文件末尾追加该行,这可以按您的预期工作。

【讨论】:

  • 这假定 127.0.0.1 行是输入流的第一行(插入应该在第二行完成)。在很多情况下这可能是正确的,但值得一提。
  • -bash: /etc/hosts: 权限被拒绝。有什么想法吗?
  • @Alex2php 确保您具有修改该文件的 root 访问权限。
  • 这个为我解决了: sudo -- sh -c "echo test >> /etc/hosts" 如果我​​尝试附加一些东西,sudo 不起作用......
  • 请注意,在 Mac 上,您需要指定 -i '',例如 sed -i '' '2i192.241.11.22 venus.example.com venus' /etc/hosts。 Mac 版的 sed 需要 -i 的扩展参数,即使它是空的。
【解决方案2】:

插入/更新条目

如果您想使用 bash 以编程方式插入/更新主机条目,这是我为此编写的脚本:

#!/bin/bash

# insert/update hosts entry
ip_address="192.168.x.x"
host_name="my.hostname.example.com"
# find existing instances in the host file and save the line numbers
matches_in_hosts="$(grep -n $host_name /etc/hosts | cut -f1 -d:)"
host_entry="${ip_address} ${host_name}"

echo "Please enter your password if requested."

if [ ! -z "$matches_in_hosts" ]
then
    echo "Updating existing hosts entry."
    # iterate over the line numbers on which matches were found
    while read -r line_number; do
        # replace the text of each line with the desired host entry
        sudo sed -i '' "${line_number}s/.*/${host_entry} /" /etc/hosts
    done <<< "$matches_in_hosts"
else
    echo "Adding new hosts entry."
    echo "$host_entry" | sudo tee -a /etc/hosts > /dev/null
fi

该脚本旨在用于 OS X,但也可以在 linux 上运行,只需稍作调整即可。

【讨论】:

  • 脚本太复杂,不能只添加一行
  • 这是一个更好的解决方案,只需向 etc/hosts imo 添加一行
  • 这很完美,虽然更新部分没有按预期工作,但即使存在 ipaddress 和 hostname 组合,它仍然继续添加该行。还做了一些调整,以便脚本不会硬编码,而是将 ipaddress 和主机名作为参数。
  • 太好了,谢谢!只需将 grep 正则表达式稍微更改为 grep -n "^[^#]*${host_name}" /etc/hosts 以忽略注释行中的潜在匹配
【解决方案3】:

如果你在 mac 或者你需要 sudo 权限,试试这个:

sudo -- sh -c -e "echo '192.34.0.03   subdomain.domain.com' >> /etc/hosts";

它仍然会要求您输入密码。

@kainjow 的另一种方式

echo '192.34.0.03 subdomain.domain.com' | sudo tee -a /etc/hosts

【讨论】:

  • 你也可以使用tee:echo '192.34.0.03 subdomain.domain.com' | sudo tee -a /etc/hosts
  • 这似乎也是 ubuntu 16 的情况。
  • 完美,正是我想要的。我很想知道-- sh -c -e 到底做了什么?我更愿意知道我在终端里放了什么,而不是仅仅复制粘贴:)
  • 你不需要-e
  • @powerbuoy 在 shell 命令中使用双标 -- 表示命令选项的结束,之后只接受位置参数。 sh 是与标志 -c 一起使用的 shell 命令解释器,它导致从字符串操作数而不是标准输入读取命令。 -e 标志对于我们的用例来说是不必要的,但是如果任何未经测试的命令在非交互模式下失败,它会导致解释的命令立即退出。
【解决方案4】:
echo "127.0.0.1 localhost `hostname`">./temp_hosts
echo "192.241.xx.xx  venus.example.com">>./temp_hosts
cat /etc/hosts |tail -n +2 >>./temp_hosts
cat ./temp_hosts > /etc/hosts
rm ./temp_file

【讨论】:

  • 感谢您的回复,弗拉基米尔。我也会测试你的方法并发布它是否对我有用,以使任何未来的访问者受益于这个问题。
  • @Ingo 你真的认为建议某人尝试某事(假设该事不危险)是否合适?让男人做实验!
【解决方案5】:

我应该指出,sedstream 编辑器)实际上并非用于编辑文件,尽管它可以用来执行此操作。 (Standard sed 除了标准输出之外没有内置的写入机制。)更合适的工具是ed

下面的 ed 脚本说“找到包含(诚然草率的)正则表达式 /127.0.0.1/ 的行并附加到下一行。” (唯一的句号告诉 ed 停止追加。)

ed /etc/hosts <<-'EOF'
    /127.0.0.1/a
    192.241.xx.xx  venus.example.com
    .
    wq
EOF

也就是说,您实际上可以非常简单地将这一行附加到 /etc/hosts 文件的 end 中:

echo '192.241.xx.xx  venus.example.com' >> /etc/hosts

【讨论】:

  • 我以前从未使用过ed。它看起来非常强大,并且会派上用场。谢谢分享。
  • 对于某些用户,根据他们的权限设置,您可能需要sudo -- sh -c "echo '192.241.xx.xx venus.example.com' &gt;&gt; /etc/hosts",因为简单地sudo echo ... 将导致permission denied
【解决方案6】:

尝试使用 root 访问权限。

 public void edithost() {
    sudo("echo " + "192.168.43.1     www.openrap.com openrap" + " >> /etc/hosts");
    sudo("echo " + "192.168.43.1  openrap.com openrap" + " >> /etc/hosts");
    sudo("echo " + "192.168.2.144  www.openrap.com openrap" + " >> /etc/hosts");
    sudo("echo " + "192.168.2.144  openrap.com openrap" + " >> /etc/hosts");
}

sudo 获得超级用户权限

public static void sudo(String... strings) {
    try {
        Process su = Runtime.getRuntime().exec("su");
        DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());

        for (String s : strings) {
            outputStream.writeBytes(s + "\n");
            outputStream.flush();
        }

        outputStream.writeBytes("exit\n");
        outputStream.flush();
        try {
            su.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这会将这些行附加到android中的主机

【讨论】:

    【解决方案7】:

    你可以使用sed,比如:

    sed '/Venus/ a\  
    192.241.xx.xx  venus.example.com venus' /etc/hosts
    

    【讨论】:

      【解决方案8】:

      我从 bash 脚本中尝试了以上所有方法。没有工作。 于是我就这样用了:

      chmod 777 /etc/hosts
      echo "127.0.0.1 $HOSTNAME" >> /etc/hosts
      chmod 644 /etc/hosts
      

      不理想,但至少有效...

      【讨论】:

        猜你喜欢
        • 2017-04-17
        • 2011-08-20
        • 1970-01-01
        • 2014-12-13
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        相关资源
        最近更新 更多