sshpass在Bash的while read循环中执行后中断问题求助
问题原因
ssh命令默认会读取标准输入(也就是你while read循环用来读取hosts.txt的输入流),当第一个ssh执行时,它会把hosts.txt里剩下的所有内容都当作自己的输入吃掉,导致后续的read命令再也读不到任何行,循环直接中断。
解决方法
给ssh命令加上-n参数,这个参数会强制ssh从/dev/null读取输入,不会占用循环的标准输入流。同时可以优化代码结构,减少重复冗余:
修改后的完整代码
#!/bin/bash while IFS=, read -r name ip; do # 根据设备类型匹配对应的配置命令 case "$name" in *ARISTA*|*NEXUS*|*ARUBA*) cmd="show running-config" ;; *R1*) cmd="show configuration | display set" ;; *HP*) cmd="display current-configuration" ;; *) echo "$name ($ip) not found" continue ;; esac # 执行ssh命令,-n参数避免占用循环的标准输入 results=$(sshpass -f/root/cred ssh -n user@"$ip" "$cmd") echo "$results" done < /root/hosts.txt
关键优化点
- ssh加
-n参数:彻底解决ssh占用输入流导致循环中断的核心问题 - 用
IFS=, read -r name ip替代awk:直接通过read分割逗号分隔的行,不需要额外调用外部命令,更高效简洁 - case语句替代多分支if:代码结构更清晰,同类设备可以合并处理,后续新增设备类型也更容易维护
continue跳过未知设备:避免无效分支的冗余执行,逻辑更顺畅
其他可选方案
如果不想用-n参数,也可以将ssh的输入直接重定向到/dev/null,效果完全一致:
results=$(sshpass -f/root/cred ssh user@"$ip" "$cmd" < /dev/null)
内容的提问来源于stack exchange,提问作者Saisuk
相关产品推荐
相关产品推荐

