最终目标是让我的bash脚本在多个服务器上执行命令。我几乎已经设置好了。我的SSH身份验证工作正常,但这个简单的while循环正在扼杀我。当我执行while循环,读取我的文件中的主机名时,它运行
时工作正常ssh $ HOST“uname -a”
但是当我尝试运行另一个ssh命令时,
ssh $ HOST“oslevel -s”
while循环提前结束!我无法弄清楚。 为什么while读取do循环在第一个命令中完全正常运行,但是在第二个命令添加时却没有?
我有一个名为hosts.list的简单文本文件,它有4个主机名,每行一个。
$ cat hosts.list
pcced1bip04
pcced1bit04
pcced1bo02
pcced1bo04
$ cat getinfo.bash
#!/bin/bash
set -x
while read HOST
do
echo $HOST
ssh $HOST "uname -a"
#ssh $HOST "oslevel -s"
echo ""
done < hosts.list`
当它运行时,它工作正常。它逐行浏览文件并获得"uname -a"
的结果。所以一切都很好,对吗? (抱歉,我打开了set -x
)。
$ ./getinfo.bash
+ read HOST
+ echo pcced1bip04
pcced1bip04
+ ssh pcced1bip04 'uname -a'
AIX pcced1bip04 1 6 0001431BD400
+ echo ''
+ read HOST
+ echo pcced1bit04
pcced1bit04
+ ssh pcced1bit04 'uname -a'
AIX pcced1bit04 1 6 0001431BD400
+ echo ''
+ read HOST
+ echo pcced1bo02
pcced1bo02
+ ssh pcced1bo02 'uname -a'
AIX pcced1bo02 1 6 0009FE2AD400
+ echo ''
+ read HOST
+ echo pcced1bo04
pcced1bo04
+ ssh pcced1bo04 'uname -a'
AIX pcced1bo04 1 6 0009FE2AD400
+ echo ''
+ read HOST
$
当我启用行 [ssh $ HOST“oslevel -s”]时会出现问题。当我这样做时,脚本只读取文件的第一行,然后停止。 为什么不进入其他界限?
$ ./getinfo.bash
+ read HOST
+ echo pcced1bip04
pcced1bip04
+ ssh pcced1bip04 'uname -a'
AIX pcced1bip04 1 6 0001431BD400
+ ssh pcced1bip04 'oslevel -s'
6100-06-02-1044
+ echo ''
+ read HOST
$
如果我的脚本出现问题,为什么在while循环中仅使用[ssh $HOST "uname -a"]
就可以正常工作?
答案 0 :(得分:5)
如果在循环内运行从stdin读取的命令(例如ssh
),则需要确保:
...否则,该命令可能会消耗用于循环的输入,导致它结束。
前者:
while read -u 5 -r hostname; do
ssh "$hostname" ...
done 5<file
...使用bash 4.1或更新版本,可以使用自动文件描述符分配重写,如下所示:
while read -u "$file_fd" -r hostname; do
ssh "$hostname" ...
done {file_fd}<file
后者:
while read -r hostname; do
ssh "$hostname" ... </dev/null
done <file
...也可以,对于单独的ssh,也可以使用-n
参数(也可以从/dev/null
重定向stdin)来近似:
while read -r hostname; do
ssh -n "$hostname"
done <file
答案 1 :(得分:1)
在循环之前分配给数组,这样就不会将stdin用于循环变量。然后循环中的ssh
可以使用stdin而不会干扰你的循环。
readarray a < hosts.list
for HOST in "${a[@]}"; do
ssh $HOST "uname -a"
#...other stuff in loop
done
答案 2 :(得分:0)
正如指定的解决方案here使用-n
的{{1}}选项或使用不同句柄打开文件:
ssh
答案 3 :(得分:-1)
可能使用python XD
#!/usr/bin/python
import sys
import Queue
from subprocess import call
logfile = sys.argv[1]
q = Queue.Queue()
with open(logfile) as data:
datalines = (line.rstrip('\r\n') for line in data)
for line in datalines:
q.put(line)
while not q.empty() :
host = q.get()
print "++++++ " + host + " ++++++"
call(["ssh", host, "uname -a"])
call(["ssh", host, "oslevel -s"])
print "++++++++++++++++++++++++++"