CentOS使用expect批量远程执行脚本和命令

本文介绍如何使用expect工具在CentOS上批量操作多台服务器,包括文件上传、执行命令和重启服务等,通过示例脚本展示具体操作流程。
导读我们有时可能会批量去操作服务器,比如批量在服务器上上传某个文件,安装软件,执行某个命令脚本,重启服务,重启服务器等,如果人工去一台台操作的话会特别繁琐,并浪费人力。

这时我们可以使用expect,向目标服务器上发送指令去实现批量操作。

下面的例子将在centos上将一个文件,批量拷贝到其他服务商上,并执行相应的命令

1. 在centos上安装expect

yum install expect

2. 编写expect脚本 copyfilebatch.sh

下面的脚本将向内网IP为 192.168.0.102 至 192.168.0.112 的服务器分别拷贝一个rc.local文件,拷贝成功后,执行chmod命令,分别重启服务器

#!/usr/bin/expect -f
set password rootpassword

for {set i 102} {$i <= 112} {incr i} {
  set ip "192.168.0.$i"
  puts "$ip"


  spawn ssh -o StrictHostKeyChecking=no $ip
  set timeout 3
  expect "root@$ip's password:"
  set timeout 3
  send "$password\r"
  set timeout 3
  send "exit\r"


  spawn scp /home/install/rc.local root@$ip:/etc/rc.d/rc.local
  set timeout 3
  expect "root@$ip's password:"
  set timeout 3
  send "$password\r"
  set timeout 3
  send "exit\r"

  spawn ssh root@$ip

  expect {
  "*yes/no" { send "yes\r"; exp_continue}
  "*password:" { send "$password\r" }
  }
  expect "#*"

  #要执行的命令
  send "chmod +x /etc/rc.d/rc.local\r"
  send "reboot\r"
  send "exit\r"
  expect eof
}

以上就是本文的全部内容,希望对大家的学习有所帮助

Linux就该这么学

<think>嗯,用户需要的是在CentOS 7上使用expect脚本批量配置机器之间的互信操作,而且每台机器的密码不同。首先,我得确认互信操作通常是通过SSH密钥对实现的,所以可能需要生成密钥,然后分发公钥到各个机器。不过因为每台机器的密码不同,所以不能用一个通用的密码来处理,必须针对每台机器使用对应的密码。 接下来,我需要考虑如何用shell脚本结合expect来自动化这个过程。Expect是用来处理交互式命令的工具,可以自动输入密码之类的。所以大概的步骤可能是:生成SSH密钥,然后遍历一个机器列表,每个机器分别用expect脚本登录,输入对应的密码,把公钥传过去。 但是用户提到密码不同,所以可能需要一个配置文件,里面每行包含主机名、用户名、密码。然后脚本读取这个文件,逐行处理。比如,一个CSV文件或者用空格分隔的格式,比如host1 user1 pass1,host2 user2 pass2等等。 然后,生成密钥对的部分,如果还没有的话,需要先检查是否存在~/.ssh/id_rsa,如果没有就执行ssh-keygen。不过可能需要非交互式的生成,可以用ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa,这样就不会提示输入密码。 接下来,分发公钥。对于每个主机,需要用expect脚本执行ssh-copy-id,或者手动scp公钥到远程主机的authorized_keys文件中。不过ssh-copy-id可能更方便,但需要处理不同密码的情况。 不过,ssh-copy-id在遇到不同主机不同密码的时候,可能需要每个主机单独处理。这时候expect脚本可以针对每个主机,传递对应的密码。 可能的流程是:读取配置文件,逐行获取主机、用户、密码,然后使用expect脚本登录到该主机,将本地的公钥添加到远程的authorized_keys文件中。 需要注意的是,远程主机可能需要配置SSH的权限,比如StrictModes是否关闭,或者.ssh目录的权限是否正确。不过这可能超出脚本的范围,用户可能需要手动处理这些问题,或者在脚本中加入相关的处理步骤,比如在expect执行mkdir -p ~/.sshchmod 700 ~/.ssh等命令。 另外,还要考虑第一次连接时SSH会提示确认主机指纹,这会导致expect脚本卡住,所以需要在SSH命令中添加-o StrictHostKeyChecking=no选项,或者提前将主机指纹添加到known_hosts中。不过这会有些安全风险,但在自动化脚本中有时会这样处理。 所以,整个脚本的大致步骤可能是: 1. 生成SSH密钥对(如果不存在)。 2. 读取包含主机、用户、密码的配置文件。 3. 对于每个主机,使用expect脚本自动登录,并执行添加公钥的操作。 在编写expect脚本时,需要用spawn启动ssh-copy-id或者scp,然后等待密码提示,发送对应的密码,处理可能的其他提示,比如是否继续连接等。 此外,可能需要处理不同用户的home目录,比如如果远程用户的home目录不是默认的,可能需要指定正确的路径。 可能的配置文件格式: host1 user1 pass1 host2 user2 pass2 ... 然后,shell脚本循环读取每一行,调用expect脚本并传递主机名、用户名、密码作为参数。 Expect脚本的写法大概如下: #!/usr/bin/expect set host [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] spawn ssh-copy-id -i /path/to/public/key $user@$host expect { "Are you sure you want to continue connecting (yes/no/\[fingerprint\])?" { send "yes\r" exp_continue } "password:" { send "$password\r" } } expect eof 不过,可能需要更详细的处理,比如超时设置,或者错误处理,比如密码错误的情况。但用户可能只需要基础版本,所以可以先实现基本功能。 另外,需要考虑公钥的路径是否正确,比如如果是当前用户的密钥,ssh-copy-id默认会使用~/.ssh/id_rsa.pub,所以可能需要指定正确的路径。 然后,在shell脚本中,循环读取配置文件的每一行,调用expect脚本,传递参数。 可能的shell脚本结构: #!/bin/bash # 生成SSH密钥 if [ ! -f ~/.ssh/id_rsa ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa fi # 配置文件路径 CONFIG_FILE="hosts.conf" while read line; do # 忽略注释空行 [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue # 解析行内容 host=$(echo $line | awk '{print $1}') user=$(echo $line | awk '{print $2}') password=$(echo $line | awk '{print $3}') # 使用expect脚本处理 ./ssh_copy_id_expect.exp "$host" "$user" "$password" done < "$CONFIG_FILE" 然后,expect脚本ssh_copy_id_expect.exp的内容大致如前所述,但需要处理可能的其他情况,比如第一次连接确认。 需要注意权限问题,比如expect脚本需要有执行权限,配置文件中的密码可能需要适当保护,不过用户自己负责安全性。 另外,可能还需要在远程主机上执行命令,确保.ssh目录authorized_keys文件的权限正确,例如: 在expect脚本中,执行完ssh-copy-id之后,可能需要执行expect eof 或者,在ssh-copy-id之后,再通过ssh连接执行chmod命令,比如: spawn ssh $user@$host "chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys" 但这样需要再次输入密码,不过如果已经添加了公钥,可能就不需要密码了。所以可能需要先添加公钥,然后再执行这些命令,或者确保ssh-copy-id已经正确处理了这些权限。 不过ssh-copy-id通常会自动设置正确的权限,所以可能不需要额外处理。 综上所述,整个脚本的结构应该是这样的,但需要处理各种可能的错误情况,比如密码错误,网络连接问题等,但用户可能只需要基础版本,所以可以先提供基本可用的脚本,再提示用户注意事项。</think>以下是一个在CentOS 7上实现SSH互信配置的脚本方案,支持不同主机使用不同密码: --- ### 一、脚本结构 建议按以下目录结构部署: ``` ├── ssh_trust/ │ ├── hosts.conf # 主机配置信息 │ ├── deploy_trust.sh # 主控制脚本 │ └── ssh_copy.exp # expect交互脚本 ``` --- ### 二、配置文件`hosts.conf` 格式:`主机IP 用户名 密码`(支持#注释) ```bash # 示例:服务器列表(密码字段支持特殊字符) 192.168.1.10 root MyPass@123 192.168.1.11 admin Server#456 192.168.1.12 webuser Web$789 ``` --- ### 三、主脚本`deploy_trust.sh` ```bash #!/bin/bash # 生成SSH密钥对 if [ ! -f ~/.ssh/id_rsa ]; then echo -e "\n\033[34m正在生成SSH密钥对...\033[0m" ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa fi # 检查依赖 if ! rpm -q expect &>/dev/null; then echo -e "\033[33m正在安装expect工具...\033[0m" yum install -q -y expect fi # 执行互信配置 echo -e "\n\033[36m开始批量配置SSH互信...\033[0m" while read line; do [[ "$line" =~ ^# || -z "$line" ]] && continue host=$(awk '{print $1}' <<< $line) user=$(awk '{print $2}' <<< $line) pass=$(awk '{print $3}' <<< $line) echo "正在处理 $user@$host ..." # 调用expect脚本 ./ssh_copy.exp $host $user $pass done < hosts.conf echo -e "\n\033[32m互信配置完成!\033[0m" ``` --- ### 四、Expect交互脚本`ssh_copy.exp` ```expect #!/usr/bin/expect set host [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] set timeout 30 # 首次连接跳过指纹确认 spawn ssh -o StrictHostKeyChecking=no $user@$host "mkdir -p ~/.ssh; chmod 700 ~/.ssh" expect { "password:" { send "$password\r" } timeout { exit 1 } } expect eof # 传输公钥 spawn scp -p ~/.ssh/id_rsa.pub $user@$host:~/tmp.pub expect { "password:" { send "$password\r" } timeout { exit 1 } } expect eof # 追加公钥 spawn ssh $user@$host "cat ~/tmp.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && rm -f ~/tmp.pub" expect { "password:" { send "$password\r" } timeout { exit 1 } } expect eof ``` --- ### 五、使用方法 1. 创建配置文件: ```bash mkdir -p ssh_trust && cd ssh_trust cat > hosts.conf <<EOF 192.168.1.10 root actual_password1 192.168.1.11 admin actual_password2 EOF ``` 2. 赋予执行权限: ```bash chmod +x deploy_trust.sh ssh_copy.exp ``` 3. 执行脚本: ```bash ./deploy_trust.sh ``` --- ### 六、注意事项 1. 安全性建议: - 配置文件建议设置为600权限:`chmod 600 hosts.conf` - 生产环境建议使用SSH密钥+密码短语的双因素认证 2. 异常处理: - 遇到连接超时,检查网络sshd服务状态 - 出现权限错误时,确认目标服务器的.ssh目录权限为700 3. 扩展建议: - 可添加日志记录功能 - 支持批量测试互信是否成功 - 可集成Ansible等自动化工具增强管理 --- ### 七、验证方法 ```bash ssh -o PasswordAuthentication=no user@host "date" ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值