批量更改主机名

我只需要根据IP地址为所有桌面计算机重新命名主机名。例如,如果IP地址是172.29.72.25,则主机名应分配为node25;如果IP地址是172.29.72.26,则主机名应为node26,依此类推。我可以通过密钥进行SSH访问所有这些主机。我认为可以通过Bash脚本实现,有人能帮助我吗?提前感谢您的帮助。

你这样通过SSH登录一堆机器而不是配置一个带有主机名选项的DHCP服务器,有什么原因吗? - RobotHumans
我们已经为大多数机器提供了基于IP的访问,这就是为什么我没有使用DHCP服务器。 - karthick87
没错,我只是看不出一个具有静态MAC到IP映射的DHCP服务器分发主机名的区别。 - RobotHumans
当您使用SSH连接这些主机时,您是否能够使用相同的用户名和密码连接到每个主机?并且这个用户能够使用sudo吗? - user8290
我不知道这个设置在未来是否会有任何增长,但是除非你想在一年后再次提出这个问题,而且单位数量增加了一个数量级,否则我建议使用DHCP服务器。 - Huckle
@Christopher 是的,我们使用相同的用户名和密码来连接这台机器。 - karthick87
1个回答

主机名存储在/etc/hostname中。
其中address是您的IP地址列表:
for A in `cat address` ; do NODE="node`echo $A | cut -d. -f4`" ; ssh $A "echo $NODE > /etc/hostname" ; done

对于每个IP地址,我们去掉最后一个字段,加上前缀"node",然后将其写入/etc/hostname。
现在,这应该可以工作,但只有当您的用户在Ubuntu上具有对/etc/hostname的写权限时才有效,默认情况下,标准用户没有这个权限。
您可以通过STDIN向sudo传递密码;例如:echo "password" | sudo -S;请注意,这是不安全的,因为您会将密码留在shell历史记录中。可以使用history命令查找并使用history -d 删除它。
当然,不要将密码写入你的家目录下的纯文本文件中...
所以,总的来说
for A in `cat address` ; do 
    NODE="node`echo $A | cut -d. -f4`"
    ssh $A "echo 'myPassword' | sudo -S echo $NODE > /etc/hostname"
done

-- 编辑 --
如果你想在每台机器上重写hosts文件,你可以加入一点awk的技巧;将模式127\.0\.0\.替换为实际匹配你子网的模式。它会保留文件中剩余的行不变。
/^127\.0\.0\./ {
        split($1, quads, /\./)
        print $1 "\tnode" quads[4]
        next
}

{ print $0 }

这将用"节点N"替换子网中所有IP地址的主机名,其中N是IP地址的最后一个四位数。
因此,我们将这些命令添加到上面的"for A"循环中(将awk脚本压缩成一行,并根据需要进行字符转义)。我们不需要以root身份读取"/etc/hosts",但是在将其替换为写入"/tmp"之后,我们需要以root身份替换它。
ssh $A "awk '/^127\.0\.0\./ { split(\$1, quads, /\./) ; print \$1 \"\tnode\" quads[4] ; next } { print \$0 }' /etc/hosts > /tmp/hosts.new"
ssh $A "echo 'myPassword' | sudo -S mv /etc/hosts /etc/hosts.old"
ssh $A "echo 'myPassword' | sudo -S mv /tmp/hosts.new /etc/hosts"

可能行不通。因为我们还需要在/etc/hosts中更改主机名。请检查并更新你的回答。 - karthick87
已经在所有机器上配置了静态IP,我现在不想分配IP地址。我只想更改主机名。 - karthick87