Linux Shell脚本while read Line中调用SSH时出现只执行一次的问题

在使用SSH执行远程命令时,遇到循环读取主机名执行命令仅运行一次的问题。原因在于SSH一次性读取所有输入,导致后续循环无内容可读。解决办法是在SSH命令后指定空输入或使用-n参数,并在执行命令前加载环境变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在写zookeeper群起脚本时,将主机名先写好在一个文本中,然后在群起脚本中循环读取主机名,然后使用ssh远程执行命令,发现只执行一次就退出了,但是把ssh远程命令注销之后可以完整的将while循环执行完毕。

参考:http://bbs.chinaunix.net/thread-3582099-1-1.html

https://blog.youkuaiyun.com/eclipse_c/article/details/51912115

发现ssh在执行时会进行读取所有的输入,会把读取文件剩下的都读入,导致在第二次执行时没有内容可读,因此会退出while循环

解决办法,在while循环中我们可以指定 ssh的读取为空,可以在ssh command 后指定一个为空的输入,< /dev/null,或者在ssh 后加上 -n , ssh -n command等同于 < /dev/null

 

在使用ssh执行远程命令时,不会执行用户登录操作,因此可能缺少一些变量,我们可以使用 ssh -n "source /etc/profile; command"在执行的命令前加载环境变量,

 

### 编写 Shell 脚本实现 SSH 登录远程 CentOS 并执行命令 为了满足需求,可以编写一个简单的 Shell 脚本来完成从本地 CentOS 服务器通过 SSH 连接到远程 CentOS 服务器并执行预设命令的任务。以下是完整的解决方案: #### 脚本功能描述 该脚本会读取目标主机列表文件 `hostlist.txt` 中的内容,并依次尝试通过 SSH 登录到每台远程服务器上运行指定的命令。如果尚未配置无密码登录,则可以通过 Expect 工具自动输入密码。 --- #### 完整脚本代码 ```bash #!/bin/bash # Author: AI Assistant # Created Time: YYYY/MM/DD # Script Description: 使用SSH连接至远程CentOS服务器并执行预定义命令 KEY_FILE=~/.ssh/id_rsa COMMAND="uptime && df -h" # 预设要执行命令,可以根据实际需求修改 if [ ! -f ${KEY_FILE} ]; then echo "RSA key does not exist, generating new one..." ssh-keygen -t rsa -N "" -f ${KEY_FILE} fi yum -y install expect >/dev/null 2>&1 # 确保已安装expect工具 while read line; do USER="root" IP=$(echo $line | cut -d " " -f 1) PASSWD="your_password_here" if ! ssh -o StrictHostKeyChecking=no ${USER}@${IP} exit; then echo "Setting up passwordless login to ${IP}" /usr/bin/expect <<EOF set timeout 10 spawn ssh-copy-id -i ${KEY_FILE}.pub ${USER}@${IP} expect { "yes/no" { send "yes\r"; exp_continue } "password:" { send "${PASSWD}\r" } } expect eof EOF fi echo "Executing command on ${IP}:" ssh -o StrictHostKeyChecking=no ${USER}@${IP} "${COMMAND}" || echo "Failed to execute command on ${IP}" done < hostlist.txt ``` --- #### 参数说明 - **`KEY_FILE`**: 指定 RSA 密钥路径,默认为 `~/.ssh/id_rsa`。 - **`COMMAND`**: 设置要在远程服务器上执行的具体命令,当前示例中使用的是 `"uptime && df -h"`[^1]。 - **`hostlist.txt`**: 主机列表文件,每一行应包含一个目标服务器的 IP 地址或域名。 - **`PASSWORD`**: 替换为目标服务器 root 用户的实际密码。 --- #### 关键技术点解析 1. **无密码登录设置** 如果未预先配置好无密码登录机制,脚本会在首次访问某台服务器调用 `ssh-copy-id` 将公钥复制过去。此过程借助 Expect 自动化处理可能遇到的身份验证提示[^2]。 2. **Expect 的作用** Expect 是一种用于自动化交互式程序的强大工具,在这里被用来模拟用户手动输入密码的行为[^3]。 3. **错误检测与日志记录** 对于每次 SSH 连接操作的结果进行了基本判断;一旦失败则打印相应消息以便排查问题所在。 4. **批量管理多台设备** 利用循环结构配合外部文本文件存储待维护的目标机器清单,从而轻松达成对众多节点的同操控目的。 --- ### 注意事项 - 执行前需赋予脚本执行权限: ```bash chmod +x script_name.sh ``` - 修改变量中的敏感数据(如密码字段),确保安全性。 - 若涉及生产环境部署,请务必遵循公司内部安全策略指南。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值