bash脚本在循环中ssh多个服务器并发出命令

时间:2013-11-27 23:10:01

标签: bash ssh

我有一个文本文件,其中有一个服务器列表。我正在尝试从服务器中的文件SSH逐个读取服务器,并执行ls以查看目录内容。当我运行SSH命令时,我的循环只运行一次,但是,对于SCP,它运行文本文件中的所有服务器并退出,我希望循环运行直到SSH文本文件的末尾。以下是我的bash脚本,如何在执行SSH时为文本文件中的所有服务器运行?

#!/bin/bash
while read line
do
    name=$line
    ssh abc_def@$line "hostname; ls;"
#   scp /home/zahaib/nodes/fpl_* abc_def@$line:/home/abc_def/
done < $1

我将脚本作为$ ./script.sh hostnames.txt

运行

4 个答案:

答案 0 :(得分:14)

此代码的问题是ssh开始从stdin读取数据,您打算将其用于read line。您可以告诉ssh从其他内容中读取内容,例如/dev/null,以避免吃掉所有其他主机名。

#!/bin/bash
while read line
do
    ssh abc_def@"$line" "hostname; ls;" < /dev/null
done < "$1"

答案 1 :(得分:8)

更直接的是使用-n标志,它告诉ssh不要从标准输入读取。

答案 2 :(得分:2)

将循环更改为for循环:

for server in $(cat hostnames.txt); do
    # do your stuff here
done

它不是并行ssh但它有效。

答案 3 :(得分:2)

我开源了一个名为Overcast的命令行工具,使这种事情变得更容易。

首先导入服务器:

overcast import server.01 --ip=1.1.1.1 --ssh-key=/path/to/key
overcast import server.02 --ip=1.1.1.2 --ssh-key=/path/to/key

完成后,您可以使用通配符在它们之间运行命令,如下所示:

overcast run server.* hostname "ls -Al" ./scriptfile
overcast push server.* /home/zahaib/nodes/fpl_* /home/abc_def/