zoukankan      html  css  js  c++  java
  • expect免交互

    shell编程中可能碰到需要交互的场景,一般有两种方式:

    1、 <<EOF  XXXX    EOF 方式

    2、expect

    第一种方式适合于简单的固定输入方式,比如输入 y 或 n。

    localhost:/test # cat a
    a
    localhost:/test # cat /root/a
    b
    localhost:/test # cp a /root/a
    localhost:/test # echo b > /root/a
    localhost:/test # cat /root/a
    b
    localhost:/test # cat a
    a
    localhost:/test # cp -i a /root/a
    cp: overwrite `/root/a'?
    localhost:/test # cat /root/a
    b
    localhost:/test # cp -i a /root/a <<EOF
    > y
    > EOF
    cp: overwrite `/root/a'? localhost:/test # cat /root/a
    a
    localhost:/test #

    第二种方式功能比较强大,但是需要 expect 软件支持。

    下面主要说第二种方式:

    Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。
    CentOS安装:yum install expect
    Ubuntu安装:sudo apt-get install expect
    1>.免交互登陆,查看远程主机磁盘分区
    #!/usr/bin/expect
    set ip 192.168.1.156
    set pass 123.com
    set timeout 30
    spawn ssh root@$ip
    expect {
    "(yes/no)" {send "yes "; exp_continue}
    "password:" {send "$pass "}
    }
    expect "root@*" {send "df -h "}
    expect "root@*" {send "exit "}
    expect eof

    2>.在Shell脚本中嵌入Expect语法
    方法1:使用EOF,将内容段让expect执行
    #!/bin/bash
    user=root
    pass='123'
    ip='192.168.1.154'
    /usr/bin/expect << EOF
    set timeout 30
    spawn ssh $user@$ip
    expect {
    "(yes/no)" {send "yes "; exp_continue}
    "password:" {send "$pass "}
    }
    expect "root@*" {send "df -h "}
    expect "root@*" {send "exit "}
    expect eof
    EOF

    #!/bin/bash
    user=root
    pass='123'
    ip='192.168.1.154'
    expect -c "
    spawn ssh $user@$ip
    expect {
    "(yes/no)" {send "yes "; exp_continue}
    "password exp_continue}
    "root@*" {send "df -h exit "; exp_continue}
    }"

    方法2:将expect脚本独立出来
    # vi login.exp #免交互登陆脚本
    #!/usr/bin/expect
    set ipaddress [lindex $argv 0]
    set username [lindex $argv 1]
    set password [lindex $argv 2]
    if { $argc != 3 } {
    puts "Usage: expect login.exp ipaddress username password"
    exit 1
    }
    set timeout 30
    spawn ssh $username@$ipaddress
    expect {
    "(yes/no)" {send "yes "; exp_continue}
    "password:" {send "$password "}
    }
    expect "$username@*" {send "df -h "}
    expect "$username@*" {send "exit "}
    expect eof

    # vi user_info #用户信息文件
    192.168.1.156 user user
    192.168.1.154 root 123.com
    # vi expect.sh #读取用户信息并赋值到变量
    #!/bin/bash
    for ip in `awk '{print $1}' user_info`
    do
    user=`awk -v I="$ip" '{if(I==$1)print $2}' user_info`
    pass=`awk -v I="$ip" '{if(I==$1)print $3}' user_info`
    expect login.exp $ip $user $pass
    done

    普通自动切换到root脚本,并且在shell中嵌入expect
    #!/bin/bash
    /usr/bin/expect << EOF
    spawn /bin/su -
    expect "Password: "
    send "123 "
    expect "*#"
    interact
    expect eof
    EOF
    或者单独写一个脚本,实现普通用户自动切换到root用户,去掉上面脚本中的#!/bin/bash,和EOF,然后把这个脚本放在/usr/bin目录中,把脚本名改为root,然后执行root命令就可以实现切换。

    参数说明:
    set:可以设置超时,也可以设置变量
    timeout:expect超时等待时间,默认10S
    spawn:执行一个命令
    expect "":匹配输出的内容
    exp_continue:继续执行下面匹配
    :可以理解为回车
    $argc:统计位置参数数量
    [lindex $argv 0]:脚本后第一个参数,类似于shell中$1,以此类推
    puts:打印字符串,类似于echo
    awk -v I="$ip":赋值变量
    expect{...}:输入多行记录

    其他参数说明:
    timeout -1:永不超时退出
    log_file /var/log/expect.log:记录交互信息,一般crontab时使用
    interact:交互后不退出远程终端,如果加要把expect "root@*" {send "exit "}注释掉,如果不加,就直接退出

    将spawn ssh root@$ip换成spawn ssh -o StrictHostKeyChecking=no root@ip既不会再提示是否将服务器计算机密钥加入本地known_hosts

  • 相关阅读:
    百度地图开发 InfoBox 弹出消息框使用详解!某物流网应用
    百度地图api画圆 标注 搜索周边功能
    有用的linux操作命令
    php后台守护进程 sh脚本 三个文件 让您的后台php永不止步
    CLR via C# 第二章 (1)
    CLR via C# 第一章 (2)
    CLR via C# 第一章(3)
    ios 画图总结
    简析 iOS 程序图标的设计
    10个必需的iOS开发工具和资源 http://coolshell.cn/articles/5089.html
  • 原文地址:https://www.cnblogs.com/smallfishy/p/12917411.html
Copyright © 2011-2022 走看看