zoukankan      html  css  js  c++  java
  • expect 自动完成交互式程序神器

    expect 安装

    yum -y install expect              # Centos
    sudo apt-get install expect # Ubuntu

    作用:自动填写交互式程序的值.

    原理:通过读取交互式问题的关键字来判断具体执行什么操作

    特性:

    • 一个expect 块负责一个交互问题,若expect块里的条件不匹配问题,则等待超时时间(timout),然后检测下一个expect块语句.
    • 一个expect块里可以同时存在多个匹配关键字符串,若其中一个字符串匹配成功,执行完相应的操作后直接退出该
      expect块,下一个交互式问题交给下一个expect块处理,不会再重新考虑expect块的其他条件
    • 如果想在expect语句块里,某个条件命中后继续使用当前的expect块匹配处理下一个交互式问题,则需要在命中的
      语句后面加上:exp_continue,但注意这容易产生死循环,请确保匹配字符串是唯一的
    • 可以在expect语句块里面使用eof来实现条件逻辑或判断.

    相关参数:

    timeout     设置匹配等待的超时时间
    spawn 创建一个通道使得expect上下文中可以执行shell命令
    expect 设置期望值,即交互式问题中预期绘出现的关键字,及再匹配成功后采取相应的动作
    send 发送的字符串,比如输入登陆的账号密码,linux使用 代表回车按键
    set 初始化变量
    interact 将控制权交给终端,否则绘退出登陆

    expect主要是在自动化登陆方面用的比较多,这里列举一个例子来说明expect的用途

    在账号密码提前写好,然后自动的ssh登陆服务器,通过expect脚本就可以实现

    文件名:[login.exp]

    #!/usr/bin/expect
    
    set host 192.168.1.2
    set port 22
    set user root
    set pass yourPassWD
    
    spawn ssh $user@$host -p $port
    
    expect {
      "yes/no" {send "yes
    "}
      "password:" {send "$pass
    "}
    eof
      "password:" {send "$pass
    "}
    }
    
    expect "$user@"
    send "cd /tmp
    "
    send "echo login successfully
    "
    
    interact

    执行测试

    root@demon-PC:/project# expect login.exp
    spawn ssh root@192.168.1.2 -p 22
    root@192.168.1.2's password:
    Last login: Thu Feb  8 22:41:31 2018 from 192.168.1.104

    Welcome to Demon Server !

    [root@demon ~]# cd /tmp
    [root@demon tmp]# echo login successfully
    login successfully

    批量登陆处理服务器

    expect支持从外部传入参数,然后进行处理,通过if语句判断参数个数,来选择ssh登陆的类型

    1.密码登陆  (4个参数)

    2.密钥登陆  需指明密钥文件路径(5个参数)

    将账号密码写入到一个文件里头

    文件名:[loginfile]

    192.168.1.2    22    root    123456
    192.168.1.3    22    root    123123
    192.168.1.4    22    root    keyPass    /root/.ssh/id_rsa

    通过awk读取文件,将其作为参数传给expect

    文件名:[login.sh]

    #!/bin/bash
    #@Author:Demon
    awk ' { host = $1; port = $2; user = $3; pass = $4; if($5)system("expect /tmp/ssh.exp "host" "port" "user" "pass" "$5); else system("expect /tmp/ssh.exp "host" "port" "user" "pass); }' loginfile

    expect接收参数,并进行ssh登陆

    文件名:[ssh.exp]

    !/usr/bin/expect
    #@Author:Demon

    # How to use
    ? # ssh.exp 192.168.1.2 22 root youSSHPassWd # ssh.exp 192.168.1.2 22 root youKeyPassWd /path/to/RSA.rsa #MUST set REMOTE_HOST [lindex $argv 0] set REMOTE_PORT [lindex $argv 1] set REMOTE_USER [lindex $argv 2] set REMOTE_PASS [lindex $argv 3] set REMOTE_RSA [lindex $argv 4] set TIMEOUT 3 if { "$argc" == "4" } { spawn ssh $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT expect { "yes/no" {send "yes ";exp_continue} #first ssh login banner "password:" {send "$REMOTE_PASS "} eof "password:" {send "$REMOTE_PASS "} eof "Permission denied" {spawn echo "need the path to rsa file"} #if no path to RSA file } } elseif { "$argc" == "5" } { spawn ssh $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT -i "$REMOTE_RSA" expect { "yes/no" {send "yes ";exp_continue} #first ssh login banner "Enter passphrase for key" {send "$REMOTE_PASS "} eof "Enter passphrase for key" {send "$REMOTE_PASS "} } } else { spawn echo "Too few Parameters" spawn echo "How to use?" spawn echo "ssh.exp 192.168.1.2 22 root youSshPassWd" spawn echo "ssh.exp 192.168.1.2 22 root youKeyPassWd /path/to/RSA.rsa" } #do some thing in remote server expect "$REMOTE_USER" send "mkdir -p /tmp/hello " send "cd /tmp/hello " send "touch Hello World Demon ComeHere "
    # Written by Demon
     

    最后执行bash login.sh就可以批量处理了

    转载请指明:http://www.cnblogs.com/demonxian3/p/8433637.html

    推荐学习网址:https://www.waitig.com/linux-expect-command-for-while-and-if-else.html

  • 相关阅读:
    Python 编码错误解决方案
    Slf4j 打日志的问题 Exception 没有堆栈信息
    朋友遇到过的t厂面试题
    php 加密解密算法
    mysql replace into用法详细说明
    python3 return print 之间的差异
    mac多版本python安装 pymysql
    thinkphp 在做搜索时的注意点
    get_object_vars()
    php中var关键字的作用和意义
  • 原文地址:https://www.cnblogs.com/demonxian3/p/8433637.html
Copyright © 2011-2022 走看看