expect使用场景

有时候需要批量地执行一些操作,或者执行自动化的操作的时候,有些指令需要交互式地进行这就会有很多麻烦,linux下有一个程序交expect,它可以模拟键盘输入文本,省去人工干预交互式的指令

expect工作方式

首先使用 spawn 开启一个会话,然后使用 expect-send 对来执行交互式操作。

spawn 后面跟上一个命令操作,表示开启一个会话。expect 等待输出特定的字符串(通常是提示符),然后使用send 发送交互字符串。比如:

  1. spawn ssh username@host # 远程登录
  2. expect "*assword" # 提示为:"username@host's password:", 等待用户输入密码
  3. send "${password}\r" # 这时使用send模拟用户输入密码的字符串,完成登录验证

安装expect

正常情况下linux默认没有安装这个软件,需要自己安装;

  1. [root@localhost ~]# yum install expect -y

基本语法使用

expect可以写成独立的格式,脚本格式为

  1. #!/usr/bin/expect

也可以嵌套在shell脚本中使用

set

设置会话超时时间

set timeout 5

spawn

spawn 后面跟一个shell命令,就是开启了一个会话

例如:

  1. spwan scp f1.txt 192.168.214.111:/home

expect-send

expect接收 spwan 后面的命令执行的输出,然后和期望字符串匹配,若对应匹配则执行相应的send来发送交互信息;

expect 使用 ‘{ }’表示一组表达式,且花括号前后要留空格

例如:

  1. expect "(yes/no)" {send "yes\n"}
  2. # "(yes/no)" 是期望匹配的字符串
  3. #{ send "yes\n"; exp_continue } expect 匹配到字符串后执行模拟输入的内容

expect还可以使用多字符匹配:如下

  1. expect {
  2. "(yes/no)" { send "yes\n"; exp_continue }
  3. "password:" { send "$password\n" }
  4. }

结束符

expect eof

expect脚本必须以interact或expect eof结束,执行自动化任务通常expect eof就够了

expect一般用于登录ssh服务器,除了ssh命令输入密码外,还有scp也是需要密码输入的,因此expect与scp结合起来使用的场景也是很多的。

实例:自动推送秘钥文件到远程主机

试想,如果要实现一些自动化的工作时,免密远程登录是必不可少的,假如在部署ansible前要将ansible的秘钥文件推送给100台服务器,这个时候在脚本中使用scp指令避免不了要进行交互式地应答,(使用ansible的authoried_keys模块的方式推送就另说了)这个时候就需要使用expect来进行自动应答地执行了

编写shell脚本,在脚本中调用expect来实现自动向远处主机推送秘钥:

  1. #!/bin/bash
  2. keypath=/root/.ssh
  3. [ -d ${keypath} ] || mkdir -p ${keypath}
  4. rpm -q expect &> /dev/null || yum install expect -y
  5. ssh-keygen -t rsa -f /root/.ssh/id_rsa -P ""
  6. password=123456
  7. while read ip;do
  8. expect <<EOF
  9. set timeout 5
  10. spawn ssh-copy-id $ip
  11. expect {
  12. "yes/no" { send "yes\n";exp_continue }
  13. "password" { send "$password\n" }
  14. }
  15. expect eof
  16. EOF
  17. done < /home/ip.txt

执行结果:要分发秘钥的主机会自动生成秘钥文件并将秘钥文件推送给ip.txt文件列表中的主机

  1. [root@Ansible script]# ./autokey.sh
  2. Generating public/private rsa key pair.
  3. Your identification has been saved in /root/.ssh/id_rsa.
  4. Your public key has been saved in /root/.ssh/id_rsa.pub.
  5. The key fingerprint is:
  6. 96:4d:4b:be:be:54:d8:54:98:4c:24:be:6d:ef:6d:53 root@Ansible
  7. The key's randomart image is:
  8. +--[ RSA 2048]----+
  9. | .+oo. |
  10. | . .+. |
  11. | + . |
  12. | * B |
  13. | S * = |
  14. | . + . E|
  15. | o . .|
  16. | o . o.|
  17. | o. ..o|
  18. +-----------------+
  19. spawn ssh-copy-id 192.168.214.128
  20. The authenticity of host '192.168.214.128 (192.168.214.128)' can't be established.
  21. RSA key fingerprint is af:6f:6a:b1:40:b9:ab:c2:05:a4:04:3e:0d:df:1a:e0.
  22. Are you sure you want to continue connecting (yes/no)? yes
  23. Warning: Permanently added '192.168.214.128' (RSA) to the list of known hosts.
  24. root@192.168.214.128's password:
  25. Now try logging into the machine, with "ssh '192.168.214.128'", and check in:
  26. .ssh/authorized_keys
  27. to make sure we haven't added extra keys that you weren't expecting.
  28. spawn ssh-copy-id
  29. Usage: /usr/bin/ssh-copy-id [-i [identity_file]] [user@]machine
  30. expect: spawn id exp4 not open
  31. while executing
  32. "expect eof"

测试一下:

  1. [root@Ansible script]# ssh 192.168.214.128 'hostname'
  2. localhost.localdomain

expect配合shell 实现自动分发秘钥文件的更多相关文章

  1. ssh分发秘钥时出现错误“Permission denied (publickey,gssapi-keyex,gssapi-with-mic)”

    因为公司的服务器连接是通过xshell公钥和密码连接的,今天在ssh分发秘钥的时候出现了,下面的错误: [root@iZ2ze97cumk8opqm28h8Z .ssh]# ssh-copy-id - ...

  2. 关于git中Pageant开机启动且自动关联秘钥

    Pageant在git中主要负责和服务器端进行身份验证,但是我们每次在启动Pageant后都需要手动的加载秘钥文件,这其实是一个比较烦的过程,我们怎么能够使其自动的完成呢? 一.Pageant开机启动 ...

  3. sshd 指定端口,指定秘钥文件

     scp -i ~/test -P22219 SRC/ root@10.2.227.76:/data/ #sshd的端口指定的是22219,  -i 指定秘钥文件   指定秘钥文件需要注意的是,需要提 ...

  4. 生成秘钥文件 sn.exe(Strong Name Tool)

    Visual Studio 内置 Strong Name Tool, 我们直接运行"VS开发人员命令提示"就可以生成秘钥文件. 秘钥文件包含公钥和私钥. 来看这个例子: 在文件夹下 ...

  5. 使用CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件

    要安装kubernetes最新版集群,https://github.com/opsnull/follow-me-install-kubernetes-cluster 这个文档必须要研习一下了. 以下实 ...

  6. JAVA中使用RSA通过秘钥文件对字符串进行加密解密

    技术交流群: 233513714 //字符串进行加密算法的名称 public static final String ALGORITHM = "RSA"; //字符串进行加密填充的 ...

  7. SFTP协议生成公共秘钥文件

    [步骤] 1 ssh方式登录服务器 2 执行命令生成秘钥对 ssh-keygen -t rsa 然后给秘钥文件命名 3.查看当前目录的.ssh目录是否有authorized_keys文件 如果有则把新 ...

  8. k8s的一键分发秘钥 需要yum install expect

    #下面的密码你改改就行了 我的机器也用的123456 ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa for i in k8s-1 k8s ...

  9. ssh使用秘钥文件连接提示WARNING: UNPROTECTED PRIVATE KEY FILE!(转载)

    转自:http://www.01happy.com/ssh-unprotected-private-key-file/ 在centos 6.4下使用ssh连接远程主机时,用的是另外一个密钥,需要用-i ...

随机推荐

  1. 【LDAP】Openldap导入数据

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://jerry12356.blog.51cto.com/4308715/1851186 ...

  2. java多线程之原子变量

    看链接博客:http://blog.csdn.net/u011116672/article/details/51068828

  3. php 可逆的加密算法

    代码: <?php class Test { private $authCodeKey = 'khUvFB9pijNyCYMGZdzqeKalyg7dh'; function authCode( ...

  4. ajax多次请求的一个效果思路

    首先页面加载时候显示遮罩层 jQuery(function() { show_dialog(); //tianxie(); }); 定义一个全局数组,用于存放问题id var qar = []; 循环 ...

  5. intellijidea课程 intellijidea神器使用技巧 4-2 抽取

    1 抽取变量 Ctrl alt V 抽取变量 Ctrl alt C 抽取静态变量  顺带创建静态方法 Crrl alt F 抽取成员变量 2 抽取方法参数 Ctrl alt P 抽取参数,到方法体中 ...

  6. MySQL连接服务端的几种方式

    一.MySQL 连接本地数据库,用户名为“root”,密码“123456”: D:\>mysql -h localhost -u root -p123456 注意:“-p”和“123456” 之 ...

  7. CSS中的样式层叠机制Cascade

    CSS中的样式层叠机制Cascade 一.样式冲突   样式冲突是CSS渲染过程要解决的一个关键问题,样式冲突主要由两个原因造成: 元素包含了不同对象所赋予的样式:浏览器.用户.作者.其中,浏览器样式 ...

  8. [Maven]Eclipse集成遇到的问题

    当maven项目导入到eclipse中后使用eclipse提供的maven命令执行任意一个出现 Exception in thread "main" java.lang.Unsup ...

  9. Java—常量和变量

    关键字 Java中有特殊用途的词被称为关键字,关键字服务大小写. 标识符 标识符是用于给java程序中的变量.类.方法等命名的符号. 标识符的几条规则: 由字母.数字.下划线(_).美元符号($)组成 ...

  10. Angular2、4入门基础知识(小的概念)

    1. 使用引用符来格式化HTML代码. @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', sty ...