寻求无需自动执行额外命令的简单SSH循环脚本(Ubuntu环境)
寻求无需自动执行额外命令的简单SSH循环脚本(Ubuntu环境)
嘿,我完全懂你的需求——就是要一个能按列表挨个SSH到服务器的脚本,登录后能手动干活,退出当前会话自动连下一台,还不想装任何额外工具对吧?咱们先把你现有脚本的问题捋清楚,再给你靠谱的解决办法:
你的现有脚本问题分析
第一个for循环脚本:
你说它会输出文件路径还报错Could not resolve hostname cat,这十有八九是写脚本时**把反引号()写成了单引号(')**——要是写成for IP in 'cat /home/bb/server.txt',bash会把整个字符串当成一个IP地址,自然会去解析hostname为cat,肯定失败。就算反引号写对了,这种用cat`喂给for循环的方式也不如read命令安全(比如服务器名带空格就会出问题)。第二个while循环脚本:
它直接跳过所有服务器不交互,根源是SSH默认会从脚本的标准输入(也就是你读server.txt的那个stdin)拿数据,导致read命令一次性把整个server.txt的内容都读完了,SSH没拿到交互输入,直接就退出了。
正确的脚本实现
给你调整后的脚本,完美适配你的需求,而且完全用原生工具,不用装任何新软件:
#!/bin/bash SERVER_LIST="/home/bb/server.txt" # 逐行读取服务器列表,确保SSH交互正常 while IFS= read -r server do echo "=== 正在连接到 $server ===" # -t 强制分配伪终端,保证能正常手动操作;-p指定SSH端口 ssh -t -p 2202 "$server" echo "=== 已断开与 $server 的连接,准备连接下一台 ===" done < "$SERVER_LIST"
关键细节解释
IFS= read -r server:IFS=保证读取的整行内容不会被空格截断,-r禁止反斜杠转义,确保服务器名里的特殊字符(比如反斜杠)能被正确识别。ssh -t:这是解决交互问题的核心!强制SSH分配一个伪终端,这样你登录后就能正常输入命令、操作服务器,再也不会出现脚本跳过交互的情况。"$server":用双引号包裹变量,避免服务器名里有空格或特殊字符时出现解析错误。
小提示
- 确保
server.txt里每行只有一个服务器IP或主机名,要是有空行,可以在循环里加一行判断跳过:[[ -z "$server" ]] && continue。 - 如果已经配置了SSH免密登录,脚本会直接连接;如果需要输密码,SSH会正常提示你输入,完全不影响手动操作。
备注:内容来源于stack exchange,提问作者MilkOverflow
相关产品推荐
相关产品推荐

