我正在尝试使用各自的用户和 ssh 循环访问多个远程服务器并运行一些命令。我尝试过,类似于 shell 脚本:
#!/bin/bash
Q_HOST=host1 host2 host3 #list of hosts
Q_USER=user1 user2 user3 #list of users
for host in Q_HOST; user in Q_USER;
do
ssh $user@host df -h
done
但我认为这不是这样循环的正确方法,你们能指导我如何实现吗
答案1
假设每个主机只有一个用户,您可以将列表放入数组并循环遍历其中一个数组的索引(哪个数组并不重要):
#!/bin/bash
Q_HOST=(host1 host2 host3) #array of hosts
Q_USER=(user1 user2 user3) #array of users
for i in ${!Q_HOST[@]}; do
host="${Q_HOST[i]}"
user="${Q_USER[i]}"
ssh "$user"@"$host" "df -h"
done
您可能还想查看parallel-ssh
( pssh
) 来完成此类任务。
答案2
您分配给数组的语法略有错误,并且您的循环无法像bash
.事实上,你写的循环看起来几乎就像在 shell 中可以做的事情一样zsh
。您还忘记了对变量加双引号。
对于zsh
解决方案:
#!/usr/bin/zsh
hosts=( host1 host2 host3 host4 ) # array of hosts
users=( user1 user2 user3 user4 ) # array of users
# loop over these and do the ssh thing
for user host in ${users:^hosts}; do
ssh $user@$host df -h
done
参数替换 ${users:^hosts}
对于 shell 来说是特殊的,并且会产生来自两个数组和zsh
的元素列表,在两者之间交替。对于上面的示例,这将生成 list 。users
hosts
user1 host1 user2 host2 user3 host3 user4 host4
循环可以for
设置zsh
几个单独的变量,因此我们使用它在每次迭代中挑选用户名-主机名对并调用ssh
.
请注意,shell 中并不真正需要引用变量,zsh
因为默认情况下 shell 不会在空格上分割它们或对它们执行文件名通配。
一个bash
办法:
#!/bin/bash
hosts=( host1 host2 host3 host4 ) # array of hosts
users=( user1 user2 user3 user4 ) # array of users
# set the positional parameters to the hosts
set -- "${hosts[@]}"
# Loop over the users.
# In each iteration, ssh to $1 for $user, then
# shift the next host into $1 when done.
for user in "${users[@]}"; do
ssh "$user@$1" df -h
shift
done
这避免了处理数组索引来配对两个数组的元素。它通过循环其中一个数组的元素,同时移出另一个数组的连续元素来实现这一点,这些元素保存在位置参数列表中。
答案3
#!/bin/bash
Q_HOST="host1 host2 host3"
#list of hosts.
Q_USER="user1 user2 user3"
#list of users
for host in Q_HOST; do
for user in Q_USER; do
echo "${user}@${host}"
ssh ${user}@${host} df -h
done
done