如何使用 for 或任何循环在跃点服务器的主机列表中运行“for 循环”?

如何使用 for 或任何循环在跃点服务器的主机列表中运行“for 循环”?

想要从跃点服务器到服务器列表运行“for 循环”。如果我在单个服务器中运行 for 循环,它工作正常,但我不知道如何嵌套它并使其在跃点服务器上工作。

For 各个主机的循环输出:

$ for i in {a..b}; do echo Volume: /dev/sd$i; sudo /usr/sbin/smartctl -a /dev/sd$i | egrep -i "model|serial"; done
Volume: /dev/sda
Device Model:     TOSHIBA THNSNJ256GCSU
Serial Number:    35FS109IT88W
Volume: /dev/sdb
Model Family:     Seagate Constellation ES.3
Device Model:     ST4000NM0033-9ZM170
Serial Number:    Z1Z7EK85
$ 

下面是我通常如何从跃点服务器运行“for 循环”:

$ for i in `cat hostlist`;do echo $i;ssh $i "uptime";echo " ";done

请建议!

答案1

您可能正在寻找类似的东西:

while IFS= read -r host
do {
  printf "%s\n" "$host"
  ssh -t -- "$host" '
    for i in a b
    do
      printf "%s\n" "Volume: /dev/sd$i"
      sudo smartctl -a "/dev/sd$i" | grep -Ei "model|serial"
    done'
  } 0<&3
done 3<&0 <hostlist

我假设hostlist文件中列出了主机,每行一个。IFS=-r在这里可能是不必要的,因为主机名不太可能包含空白字符或反斜杠;不过,它们不应该受到伤害。同样,在这种情况下,在循环hostlist中读取您的for内容可能没问题,但使用while循环是一个好习惯。看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?了解更多相关信息。

对于每个主机,都会使用强制在远程主机上分配伪终端的选项来ssh调用,需要输入将询问您的密码(除非您将其配置为不这样做)。-tsudo

打开一个新的文件描述符 ( 3<&0),复制外部标准输入的文件描述符,以使后者可用于循环体({ }由于这个原因而被包装)。ssh否则将读取您的信息hostlist并无法与您互动(例如,当sudo需要您的密码时)。

我替换echoprintf因为后者是更稳健(即使这里并不是严格必要的)。我替换egrepgrep -E因为(查看 GNU 手册)前者已被弃用并且仅提供向后兼容性。

最后,我将大括号扩展 ( {a..b})替换为a b,以使脚本能够在任何 POSIX shell 中运行,包括那些不支持该功能的 shell(例如dash)。

相关内容