• 【转】使用expect实现shell自动交互


    原文地址:http://www.nginx.cn/1934.html

    shell脚本需要交互的地方可以使用here文档是实现,但是有些命令却需要用户手动去就交互如passwd、scp

    对自动部署免去用户交互很痛苦,expect能很好的解决这类问题。

    expect的核心是spawn expect send set

    spawn 调用要执行的命令
    expect 等待命令提示信息的出现,也就是捕捉用户输入的提示:
    send 发送需要交互的值,替代了用户手动输入内容
    set 设置变量值
    interact 执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。
    expect eof 这个一定要加,与spawn对应表示捕获终端输出信息终止,类似于if....endif

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

    设置expect永不超时
    set timeout -1

    设置expect 300秒超时,如果超过300没有expect内容出现,则推出
    set timeout 300

    expect编写语法,expect使用的是tcl语法。

    一条Tcl命令由空格分割的单词组成. 其中, 第一个单词是命令名称, 其余的是命令参数
    cmd arg arg arg

    $符号代表变量的值. 在本例中, 变量名称是foo.
    $foo

    方括号执行了一个嵌套命令. 例如, 如果你想传递一个命令的结果作为另外一个命令的参数, 那么你使用这个符号
    [cmd arg]

    双引号把词组标记为命令的一个参数. "$"符号和方括号在双引号内仍被解释
    "some stuff"

    大括号也把词组标记为命令的一个参数. 但是, 其他符号在大括号内不被解释
    {some stuff}

    反斜线符号是用来引用特殊符号. 例如:n 代表换行. 反斜线符号也被用来关闭"$"符号, 引号,方括号和大括号的特殊含义

    expect使用实例

    1。首先确认expect的包要安置。

    #rpm -qa | grep expect

    如果没有则需要下载安装,

    #yum install expect

    2.安装完成后,查看expect的路径,可以用

    #which expect

    /usr/bin/expect

    3.编辑脚本
    #vi autosu.sh
    添加如下内容

    #!/usr/bin/expect  -f   //这个expect的路径就是用which expect 查看的结果
    
    spawn su - nginx       //切换用户
    expect "password:"      //提示让输入密码
    send "testr"       //输入nginx的密码
    interact                //操作完成
    

    4.确定脚本有可执行权限

    chmod +x autosu.sh

    5.执行脚本 expect autosu.sh 或 ./autosu.sh

    expect常用脚本

    登陆到远程服务器

    #!/usr/bin/expect   
    set timeout 5 
    set server [lindex $argv 0] 
    set user [lindex $argv 1] 
    set passwd [lindex $argv 2] 
     
    spawn ssh -l $user $server 
    expect { 
    "(yes/no)" { send "yesr"; exp_continue } 
    "password:" { send "$passwdr" } 
    } 
    expect "*Last login*" interact 
    

    scp拷贝文件

    #!/usr/bin/expect
    set timeout 10
    set host [lindex $argv 0]        //第1个参数,其它2,3,4参数类似
    set username [lindex $argv 1]
    set password [lindex $argv 2]
    set src_file [lindex $argv 3]
    set dest_file [lindex $argv 4]
    spawn scp $src_file $username@$host:$dest_file
     expect {
     "(yes/no)?"
       {
        send "yesn"
        expect "*assword:" { send "$passwordn"}
     }
     "*assword:"
    {
     send "$passwordn"
    }
    }
    expect "100%"
    expect eof
    

    使用方法
    ./expect_scp 192.168.75.130 root 123456 /root/src_file /root/dest_file
    以上的命令执行后,将把本地/root目录下的src_file文件拷贝到用户名为root,密码为123456的主机192.168.75.130中的/root下,同时还将这个源文件重命名为dest_file

    一样例:

    自动建立ssh信任脚本

    在工作中经常遇到给两台主机建立ssh信任,手动建立太费事了,索性胡乱写了个脚本ssh_trust.sh来自动建立信任:

    1. #!/bin/bash
    2. src_host=$1
    3. src_username=$2
    4. src_passwd=$3
    5. dst_host=$4
    6. dst_username=$5
    7. dst_passwd=$6
    8. #在远程主机1上生成公私钥对
    9. Keygen()
    10. {
    11. expect << EOF
    12. spawn ssh $src_username@$src_host ssh-keygen -t rsa
    13. while 1 {
    14.         expect {
    15.                         "password:" {
    16.                                         send "$src_passwd "
    17.                         }
    18.                         "yes/no*" {
    19.                                         send "yes "
    20.                         }
    21.                         "Enter file in which to save the key*" {
    22.                                         send " "
    23.                         }
    24.                         "Enter passphrase*" {
    25.                                         send " "
    26.                         }
    27.                         "Enter same passphrase again:" {
    28.                                         send " "
    29.                                         }
    30.                         "Overwrite (y/n)" {
    31.                                         send "n "
    32.                         }
    33.                         eof {
    34.                                    exit
    35.                         }
    36.         }
    37. }
    38. EOF
    39. }
    40. #从远程主机1获取公钥保存到本地
    41. Get_pub()
    42. {
    43. expect << EOF
    44. spawn scp $src_username@$src_host:~/.ssh/id_rsa.pub /tmp
    45. expect {
    46.              "password:" {
    47.                             send "$src_passwd ";exp_continue
    48.                 }
    49.                 "yes/no*" {
    50.                             send "yes ";exp_continue
    51.                 }   
    52.                 eof {
    53.                                 exit
    54.                 }
    55. }
    56. EOF
    57. }
    58. #将公钥的内容附加到远程主机2的authorized_keys
    59. Put_pub()
    60. {
    61. src_pub="$(cat /tmp/id_rsa.pub)"
    62. expect << EOF
    63. spawn ssh $dst_username@$dst_host "chmod 700 ~/.ssh;echo $src_pub >> ~/.ssh/authorized_keys;chmod 600 ~/.ssh/authorized_ke
    64. ys"
    65. expect {
    66.             "password:" {
    67.                         send "$dst_passwd ";exp_continue
    68.              }
    69.             "yes/no*" {
    70.                         send "yes ";exp_continue
    71.              }   
    72.             eof {
    73.                         exit
    74.              } 
    75. }
    76. EOF
    77. }
    78. Keygen
    79. Get_pub
    80. Put_pub
    复制代码

    脚本主要由3个expect组成,比较简单,用法是

    1. ./ssh_trust.sh host1 user1 passwd1 host2 user2 passwd2
    复制代码

    即建立从user1@host1到user2@host2的ssh信任。
    说明:
    1、当然得安装expect
    2、脚本放在第三方机器(能远程登录host1和host2)上运行即可,当然放在host1和host2上运行也行。
    3、如果想批量建立信任,可以编辑一个文件夹file如:

    1. host1 user1 passwd1 host2 user2 passwd2
    2. host3 user3 passwd3 host4 user4 passwd4
    3. host5 user5 passwd5 host6 user6 passwd6
    复制代码

    使用下面命令执行脚本即可:

    1. xargs -n6 ./ssh_trust.sh < file
    复制代码

    4、仓促写的,脚本只是简单实现功能,使用前确保参数的可用性(用户密码主机名),不然很容易报错
    5、只在linux redhat上测试过,运行成功,欢迎大家提意见~~

  • 相关阅读:
    POJ 1795 DNA Laboratory
    CodeForces 303B Rectangle Puzzle II
    HDU 2197 本源串
    HDU 5965 扫雷
    POJ 3099 Go Go Gorelians
    CodeForces 762D Maximum path
    CodeForces 731C Socks
    HDU 1231 最大连续子序列
    HDU 5650 so easy
    大话接口隐私与安全 转载
  • 原文地址:https://www.cnblogs.com/yuzhaoxin/p/4918268.html
Copyright © 2020-2023  润新知