2017-06-19 122 views
0

我试图开始使用读取-r,但目前为止没有运气。 以下脚本(在下面添加)应该从/ etc/hosts中创建一个SSH服务器列表,然后执行该命令。我用它来进行简单的管理,添加用户等等。在bash脚本中的读命令

我通常使用sshservers=($(<serverlist.txt)),但上周我通过Shellcheck运行了脚本,它说我应该用read -r代替。 所以我补充说,但现在我的脚本在我运行时卡住了。

是否有人能够帮助我解决如何正确使用read -r? (如果你有任何进一步的提示或注释,请告诉我,我仍然在学习Bash,正如你可能看到我的脚本那样)。

提前致谢!

#!/bin/bash 
serverlist=/home/demo/serverlist.txt 
: > "$serverlist" 
sed -e '/^#/d' /etc/hosts | awk '{print $2}' >> "$serverlist" 
sed -i -- '/^localhost/ d' "$serverlist" 
#sshservers=($(<serverlist.txt)) 
sshservers=$(read serverlist) 
for sshserver in "${sshservers[@]}" 
     do 
     ssh -t [email protected]"$sshserver" "hostname && sudo ls /root/" 
done 
echo "done" 

编辑:/home/demo/serverlist.txt包含IP与下面的格式,不知道这是否有助于:

192.168.1.1 
192.168.1.2 
192.168.1.3 
+2

看一看[BashFAQ/001]( http://mywiki.wooledge.org/BashFAQ/001),“我如何逐行读取文件(数据流,变量)(和/或逐场)?” –

+0

如果你有bash 4+,你可以使用mapfile'IFS = mapfile -t sshserver <“$ serverlist”' – 123

+0

@BenjaminW。感谢您的帮助。我不知道如何将这完全添加到我的脚本。 我必须删除'for'行并将其设置为'IFS = read -r sshserver; do'? – Florius

回答

1

与旧版本的bash的(如果你想在一个行阵列):

sshservers=() 
while read -r servername; do 
    sshservers+=("$servername") 
done < "$serverlist" 

bash 4+你可以使用readarray

sshservers=() 
readarray sshservers < "$serverlist" 

或在这种情况下,如果你并不真的需要在文件中servernames节点,你可以只在结果像这样的命令循环:

while read -r sshserver: do 
    ssh -t "[email protected]$sshserver" "hostname && sudo ls /root/" 
done < <(sed -e '/^#/d' /etc/hosts | awk '{print $2}' | grep -vE '^$|^localhost') 
+0

你会希望'-t'标志readarray从元素中移除换行符。 – 123

+0

嗯,我不确定是否理解第一个,以及如何在我的情况下使用它。 它只会替换'sshservers = $(读取服务器列表)'? 但我真的很喜欢你提供的第三个选项,根本不使用txt文件!我会看看如果我能做到这一点,谢谢! – Florius