不同用户的多个 ssh 会话

不同用户的多个 ssh 会话

我正在编写一个连接到使用 3 个不同用户的多个服务器的脚本。

#!/bin/ksh

server1=("abc1" "abc2")
server2=("abc3" "abc4")
server3=("abc5" "abc6")

for i in "${server1[@]}"
do ssh sam@$i "some command"
done

for i in "${server2[@]}"
do ssh danny@$i "some command"
done

for i in "${server3[@]}"
do ssh robert@$i "some command"
done

有没有一种方法可以将所有三个for循环合并为一个。实际上我只想为多个连接编写一个 ssh 。

我尝试将所有服务器放在 1 个数组中,将用户放在另一个数组中

servers=("abc1" "abc2" "abc3" "abc4" "abc5" "abc6")

users=("sam" "Danny" "Robert")

for i in ${servers[@]}
do
 ssh ${users[@]}@$i "some command"
done

但通过这种方式,脚本将每个用户放在每个服务器上,最终锁定服务帐户......

我想要的是一些循环所有服务器和用户的脚本,并且仅将用户Sam与数组匹配、server1用户与danny数组匹配server2以及用户robert与数组匹配server3。有没有更好的方法以干净、更好的方式将正确的用户与正确的服务器相匹配......

答案1

假设 Bash,正如标签所说(不是 shebang 所说的 ksh),我们可以使用名称引用使用给定整数标识符的相应数组变量:

users=(. userxyz user123 user221)
for n in 1 2 3
do
    declare -n server=server$n
    for i in "${server[@]}"
    do ssh "${users[$n]}@$i" "some command"
    done
done

使用合适的echo,我们得到与原始脚本相同的输出:

ssh userxyz@abc1 some command
ssh userxyz@abc2 some command
ssh user123@abc3 some command
ssh user123@abc4 some command
ssh user221@abc5 some command
ssh user221@abc6 some command

要适应 Korn shell,您需要使用nameref内置命令代替declare -n


更简单的方法可能只是一起考虑用户名/主机名:

servers=("userxyz@abc1" "userxyz@abc2"
         "user123@abc3" "user123@abc4"
         "user221@abc5" "user221@abc6")

for i in "${servers[@]}"
do ssh "$i" "some command"
done

答案2

如果user1只与server1a和相关联server1b,与,等user2相关联,则server2aserver2bserver2c

#!/bin/sh

set -- \
    user1 server1a server1b -- \
    user2 server2a server2b server2c -- \
    user3 server3a --

while [ "$#" -ne 0 ]; do
    user=$1; shift

    until [ "$1" = -- ]; do
        ssh "$user@$1" 'some command'
        shift
    done

    # Shift off that "--" delimiter
    shift
done

这使用位置参数来存储用户名和相应的服务器列表。由于它是单个字符串列表,因此我们将包含用户名和服务器名称的列表部分定界,--以便我们可以轻松地看到何时需要新用户名或列表末尾。

外部循环遍历列表的各个部分,并将用户名分配给变量user,而内部循环遍历服务器名称并调用,直到找到ssh字符串。--

该脚本是为/bin/sh和 编写的,因此也适用于kshbash

鉴于上面的代码,ssh将执行以下命令:

ssh user1@server1a 'some command'
ssh user1@server1b 'some command'
ssh user2@server2a 'some command'
ssh user2@server2b 'some command'
ssh user2@server2c 'some command'
ssh user3@server3a 'some command'

如果删除初始set命令,您将能够像这样从命令行调用脚本,以获得相同的效果:

$ ./script user1 server1a server1b -- user2 server2a server2b server2c -- user3 server3a --

通过在内循环中进行额外的检查 ( ),您可以在命令行中|| [ "$#" -eq 0 ]省略最后一个检查。--


如果您想做的是申请干燥原则并且仅从ssh代码中的单个点调用,然后将该位提取到函数中。这是您的代码,经过修改以执行此操作:

#!/bin/ksh

server1=("abc1" "abc2")
server2=("abc3" "abc4")
server3=("abc5" "abc6")

process () {
    ssh "$1@$2" 'some command'
}

for server in "${server1[@]}"; do
    process sam "$server"
done

for server in "${server2[@]}"; do
    process danny "$server"
done

for server in "${server3[@]}"; do
    process robert "$server"
done

相关内容