bash 脚本在循环中 ssh 多个服务器并发出命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20254906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash script to ssh multiple servers in a Loop and issue commands
提问by Zahaib Akhtar
I have a text file in which I have a list of servers. I'm trying to read the server one by one from the file, SSH
in the server and execute ls
to see the directory contents. My loop runs just once when I run the SSH
command, however, for SCP
it runs for all servers in the text file and exits, I want the loop to run till the end of text file for SSH. Following is my bash script, how can I make it run for all the servers in the text file while doing 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 <
I run the script as $ ./script.sh hostnames.txt
我运行脚本 $ ./script.sh hostnames.txt
回答by that other guy
The problem with this code is that ssh
starts reading data from stdin, which you intended for read line
. You can tell ssh
to read from something else instead, like /dev/null
, to avoid eating all the other hostnames.
这段代码的问题在于它ssh
开始从 stdin 读取数据,您打算将其用于read line
. 您可以ssh
改为从其他内容读取,例如/dev/null
,以避免吃掉所有其他主机名。
#!/bin/bash
while read line
do
ssh abc_def@"$line" "hostname; ls;" < /dev/null
done < ""
回答by Hyman
A little more direct is to use the -n flag, which tells ssh not to read from standard input.
更直接一点的是使用 -n 标志,它告诉 ssh 不要从标准输入中读取。
回答by Andrew Childs
I open-sourced a command line tool called Overcastto make this sort of thing easier.
我开源了一个名为Overcast的命令行工具,使这种事情变得更容易。
First you import your servers:
首先导入服务器:
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
Once that's done you can run commands across them using wildcards, like so:
完成后,您可以使用通配符在它们之间运行命令,如下所示:
overcast run server.* hostname "ls -Al" ./scriptfile
overcast push server.* /home/zahaib/nodes/fpl_* /home/abc_def/
回答by R.Sicart
Change your loop to a for loop:
将循环更改为 for 循环:
for server in $(cat hostnames.txt); do
# do your stuff here
done
It's not parallel ssh but it works.
它不是并行 ssh,但它有效。