在创build脚本来更新/ etc / hosts文件中的主机名时遇到多个问题?

我完全是新的脚本,因此需要帮助解决这个问题。

我们有大约3000台虚拟机和450台物理服务器,这些服务器都是基于Linux的服务器(从9.x开始很less有Ubuntu的服务器,其中很less有Susu从8.x开始,大部分是从4.x开始到7.4的RHEL)所有他们我需要添加与IP详细信息到他们各自的/ etc / hosts文件几个主机名项。

我有不同的用户在每个服务器上有完整的sudoers访问,我可以使用因此,我创build了一个主机名,用户名和密码格式的CSV文件。 其中包含需要login的详细信息。文件名是“hostname_logins.csv”

我需要上传一个文件(即hostname_list到这些服务器中的每一个,然后在每个服务器主机文件中更新这些相同的细节。

我将使用一个RHEL 6服务器运行此脚本。 (所有其他主机都可以从这台服务器parsing,可以到达,我已经确认了。)

因此需要帮助解决这个脚本。

脚本不知道有什么问题,因为我是一个新的脚本:

#!/bin/bash while read hostname_login user_name user_password do scp -p ./hostname_list $user_name:$user_password@$hostname_login:/tmp ssh -eS $user_name:$user_password@$hostname_login [bash -c "echo rishee | sudo -S mv /tmp/hostname_list ./hostname_list && cp -p /etc/hosts /etc/hosts.bkp && cat ./hostname_list >> /etc/hosts && rm -f ./hostname_list"] done < hostname_logins.csv 

我需要把它作为一个单独的脚本,可以在所有这些服务器上运行。 提前致谢。

我没有试过在shell中读取CSV,所以这将是一个不完整的答复。 我通常使用Perl或AWK来做这样的事情。

第一个问题是shell正在使用空白来分隔行中的字段,所以你必须分割“,”(逗号)上的字段。 所以

 IFS="," while read hostname_login.... 

但是,如果它是“真正的”CSV,那么它可能看起来像这样

 "hostname_login",username,"userpass" 

即它是否具有引号的可变性。 如果情况并非如此,那么你是免费的。

我不熟悉你的SSH中的[bash -c]语法,所以我不能评论它。 我倾向于使用单引号(')来代替。

我想你可以跳过将/ tmp / hostname_list移到主目录的步骤。 你可以做

  ssh -eS $user_name:$user_password@$hostname_login [echo rishee | sudo -S cp -p /etc/hosts /etc/hosts.bkp && cat /tmp/hostname_list >> /etc/hosts && rm -f /tmp/hostname_list"] 

一旦我确定这件事情是否真实,我会更新我的答案。 我只使用它在模式匹配上下文中,并作为条件testing的别名。 (即for filename in hostname[0-9]; do ...if [ -n "$var" ]; then...

ssh + sudo也会有问题,其中ssh无法分配一个pty,而sudo则会适应这个问题。 我将不得不四处寻找,但我觉得我们通过调整/etc/sudo.config或其他东西来解决这个问题,这是不太理想的。

正如所写的那样,你也只能为那个最初的mv / tmp / hostname ./hostname做sudo。

就个人而言,由于您的文件内容是静态的,所以我会通过预先写好要在另一端运行的内容来简化整个转义序列的内容,然后复制:

 cat > hostname_list_script.sh #/bin/bash if ! cp -p /etc/hosts /etc/hosts.bkp; then echo "Failed to backup /etc/hosts" exit 1 fi cat <<EOM >> /etc/hosts ^D cat hostname_list >> hostname_list_script.sh EOM ^D 

您现在正在复制的文件在顶部有一些文本,您希望添加的内容以及底部的一些文本

 [...] fi cat <<EOM >> /etc/hosts 10.90.70.5 hostname1 10.90.70.4 hostname2 10.90.70.6 hostname3 EOM 

那么你的主要脚本可以阅读

 #/bin/bash IFS="," while read hostname_login user_name user_password do scp -p ./hostname_list_script.sh $user_name:$user_password@$hostname_login:/tmp echo sudo_password | ssh -t -eS $user_name:$user_password@$hostname_login '/usr/bin/sudo -S -s bash /tmp/hostname_list_script.sh' done < hostname_logins.csv 

其实,我看到另外一个问题。 我认为你需要根据login名更改传递给sudo的密码:

  echo $user_password | ssh .... 

我认为,当login密码各不相同时,sudo会在所有机器上使用静态密码,这是值得怀疑的。

CAVEAT EMPTOR:我还没有testing上面提到的pty可用性问题,以及是否不需要引用sudo的bash script参数。 在我的脑海中,这是有效的,但你可能需要摆弄引用才能正确。 我不需要更新我的/ etc / hosts文件,所以我没有testing它。

另外Spider还提到,在您的一台机器上安装BIND(DNS Nameserver)可能会更容易,只需执行一个脚本即可将该机器的IP地址添加到/etc/resolv.conf,而不是附加到/ etc / hosts。 当我第一次开始阅读你的问题的时候,我想知道我们是否也必须参与删除主机和去除/ etc / hosts项目。 我想知道这可能是几个月后的下一个问题,当今你添加的一些主机消失或重命名。

我在制定如何做这样的事情方面的build议将会被分解。 所以首先debuggingwhile循环:

 #!/bin/bash while read hostname_login user_name user_password do echo "$hostname_login / $user_name / $user_password" done < hostname_logins.csv 

然后从hostname_logins.csv文件中获取前4行,并演示while循环的内容,首先在while循环中添加文件副本。 接下来从命令行工作到ssh执行线去一个主机。 一旦你有了一个所有的解决scheme,你就可以在脚本中的while循环中粘贴你的演化线。 在你的4台主机testing仪上重新testing一次,一旦你确定你已经完成了所有的testing,然后给它提供完整的主机列表。