2016-11-11 75 views
-1

我有一个要求,应该解决以下几点。Shell脚本 - 虽然循环/文件读取不工作

  1. 我有一个包含IP地址列表的文件,我想逐行阅读。
  2. 对于每个IP,我需要使用SSH来推动下面的命令(全部为设备的MikroTik)

    /radius add service=login address=172.16.0.1 secret=aaaa 
    /user aaa set use-radius=yes 
    

以下是我的代码。

#!/bin/bash 

filename="branch" 

while IFS= read line; do 

     echo ${line//} 
     line1=${line//} 
     ok='@' 
     line3=$ok$line1 

     sshpass -p abc123 ssh -o StrictHostKeyChecking=no admin$line3/radius add service=login address=172.16.0.1 secret=aaaa 
     sleep 3 
     sshpass -p abc123 ssh -o StrictHostKeyChecking=no admin$line3/user aaa set use-radius=yes 
     sleep 3 
     echo $line3 
     echo $line 
done <"$filename" 

分公司文本文件:

192.168.100.1 

192.168.101.2 

192.168.200.1 

问题:什么都我做的变化,而循环只运行一次。

故障排除/观察: 如果我运行While循环来读取文件“分支”,没有SSH命令它工作正常。

+0

不要使用'sshpass'!首选理解*''公钥认证''* doe的工作方式! (注意:'sshpass'可能是你奇怪问题的原因) –

+0

当你显示输入文件时是否有空行? – cdarke

回答

0

问题是循环中的程序也读取标准输入上的数据。这将消耗"$filename"中的第二行和后续行。 在循环的下一次迭代中,没有剩下可读的内容,循环终止。

解决方案是识别命令读取标准输入,可能是sshpass并将其更改为仅保留stdin。赛勒斯的答案显示了一种方法来做到这一点ssh。如果还是不行,请尝试

sshpass [options and arguments here] < /dev/null 

另一种解决方案是用for循环更换while。这个工作只要branch文件只包含IP地址:

for ip in $(cat branch); do 
    echo $ip 
    ... 
    sshpass ... 
done 
+0

感谢您的解释:) :)澄清一件事...我需要知道你的意思是什么“**问题是循环中的程序也读取标准输入数据,这将消耗第二个和后续“$ filename”中的内容在循环的下一次循环中,没有什么可以读取和循环终止**“ – methz

+0

这意味着'read'和'sshpass'都从同一个标准输入,即从'“$ filename”'。首先是'read',它读取文件名中的第一行;然后是sshpass,它读取所有其余的行。然后下一个'读'没有更多的阅读和终止循环。 – Jens