• linux expect的使用


    linux expect的使用

    来源:https://www.jianshu.com/p/b987f5e92c03

    参考:https://blog.csdn.net/houmou/article/details/53102051

    参考: https://zhuanlan.zhihu.com/p/416370937

    参考:https://www.yiibai.com/tcl

    1. expect介绍

    使用Linux的程序员对输入密码都不会陌生,比如使用超级用户执行命令,又比如scpssh连接远程主机等等。如果我们脚本里面有scp的操作,总不可能执行一次scp就输入密码一次,这样就需要一个人盯着脚本运行了。 为了解决这个问题,我们需要一个自动输入密码的功能。

    expect是建立在tcl(Tcl/Tk快速入门 )基础上的一个工具,它可以让一些需要交互的任务自动化地完成。相当于模拟了用户和命令行的交互操作。
    一个具体的场景:远程登陆服务器,并执行命令
    登录时输入密码需要交互,bash脚本无法完成,可以使用expect来完成。

    2. 安装

    brew install expect
    

    3. 原理

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

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

    4. 基本语法

    脚本解释器
    脚本中首先引入文件,表明使用的是哪一个shell

    #!/usr/bin/expect
    

    set
    设置会话超时时间为30s, 若不限制超时时间则应设置为-1

    set timeout 30
    

    set 还可以设置变量

    # 使用变量语句:$param 或者 ${param}({}用来避免param和后面的字符串拼接起来导致错误)
    set param "param_str"
    set param 1
    

    spawn
    spawn 后面跟一个命令,开启一个会话

    spawn ${cmd} # for example : spawn su root
    

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

    expect "$case1" {send "$respond1\r"} # 这一行等同于下面两行
    
    expect "$case1"
    send "$response1\r"
    

    expect 可以有多个分支,就像switch语句一样。

    expect 
    {
        "$case1" {send "$response1\r"}
        "$case2" {send "$response2\r"}
        "$case3" {send "$response3\r"}
    }
    

    结束符
    expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
    interact : 执行完成后保持交互状态, 这时可以手动输入信息
    注:expect eofinteract 二选一即可

    接收参数
    参数存在argv中,使用第一个参数如下:

    set param0 [lindex $argv 0]
    

    $argc表示参数个数,判断语句如下:

    if {$argc < 1} {
        #do something
        send_user "usage: $argv0 <param1> <param2> ... "
        exit
    }
    

    注:$argv0 是脚本名,但[lindex $argv 0]是第一个参数 param1, [lindex $argv 1]是第二个参数 param2, 以此类推 send_user 用来显示信息到父进程(一般为用户的shell)的标准输出。

    5. 实例

    实现远程登录服务器,并切换到root用户下执行关闭防火墙的命令,然后退出

    #!/usr/bin/expect
    
    if {$argc < 4} {
        #do something
        send_user "usage: $argv0 <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>"
        exit
    }
    
    set timeout -1
    set remote_user [lindex $argv 0] # 远程服务器用户名
    set remote_host [lindex $argv 1] # 远程服务器域名
    set remote_pwd [lindex $argv 2] # 远程服务器密码
    set remote_root_pwd [lindex $argv 3] # 远程服务器根用户密码
    
    # 远程登录
    spawn ssh ${remote_user}@${remote_host}
    expect "*assword:" {send "${remote_pwd}\r"}
    expect "Last login:"
    
    # 切换到 root
    send "su\r"
    expect "*assword:" {send "${remote_root_pwd}\r"}
    
    # 执行关闭防火墙命令
    send "service iptables stop\r"
    send "exit\r"
    send "exit\r"
    expect eof
    

    将代码保存到 remot_root_command.exp 中,权限改为755,然后执行下面这条命令即可:

    ./remote_root_command.exp <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>
    

    Linux expect使用方法

    来源  https://www.lxlinux.net/6637.html

    expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信,本篇文章为大家详细讲解一下Linux expect使用方法。

    expect参数

    启用选项

    • -c:执行脚本前先执行的命令,可多次使用。
    • -d:debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用exp_internal 1相似。
    • -D:启用交换调式器,可设一整数参数。
    • -f:从文件读取命令,仅用于使用#!时。如果文件名为”-“,则从stdin读取(使用”./-“从文件名为-的文件读取)。
    • -i:交互式输入命令,使用”exit”或”EOF”退出输入状态。
    • --:标示选项结束(如果你需要传递与expect选项相似的参数给脚本时),可放到#!行:#!/usr/bin/expect --
    • -v:显示expect版本信息。

    expect的4个命令

    Expect中最关键的四个命令是send,expect,spawn,interact。

    命令说明
    send 用于向进程发送字符串
    expect 从进程接收字符串
    spawn 启动新的进程
    interact 允许用户交互

    常用命令

    `# 命令行参数`
    `# $argv,参数数组,使用[lindex $argv n]获取,$argv 0为脚本名字`
    `# $argc,参数个数`
    `set` `username [lindex $argv 1]` `# 获取第1个参数`
    `set` `passwd` `[lindex $argv 2]` `# 获取第2个参数`
    `set` `timeout 30` `# 设置超时`
    `# spawn是expect内部命令,开启ssh连接`
    `spawn` `ssh` `-l username 192.168.1.1`
    `# 判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间(timeout)后返回`
    `expect` `"password:"`
    `# 发送内容ispass(密码、命令等)`
    `send` `"ispass\r"`
    `# 发送内容给用户`
    `send_user` `"$argv0 [lrange $argv 0 2]\n"`
    `send_user` `"It's OK\r"`
    `# 执行完成后保持交互状态,控制权交给控制台(手工操作)。否则会完成后会退出。`
    `interact`
    

    命令介绍

    • close:关闭当前进程的连接。

    • debug:控制调试器。

    • disconnect:断开进程连接(进程仍在后台运行)。

      • 定时读取密码、执行priv_prog
           `send_user` `"password?\ "`
           `expect_user -re` `"(.*)\n"`
           `for` `{} 1 {} {`
           `if` `{[fork]!=0} {``sleep` `3600;``continue``}`
           `disconnect`
           `spawn priv_prog`
           `expect Password:`
           `send` `"$expect_out(1,string)\r"`
           `. . .`
           `exit`
           `}`
    
    • exit:退出expect。
    • exp_continue [-continue_timer]:继续执行下面的匹配。
    • exp_internal [-f file] value:

    expect范例

    1.远程登录并创建文件后退出
    #!/usr/bin/expect           
    ##注意路径,使用 [whereis expect] 查看
    set user "hadoop"           
    ##设定参数,注意",'的区别
    set pwd "yangkun"
    set host "48.93.36.144"
    set timeout -1              
    ##;号可有可无 spawn ssh -p 2020 $user@$host expect {                    ##expect后有空格    "*yes/no" {send "yes\r"; exp_continue}    "*password:" {send "$pwd\r"} } expect "]*"                 ## 通配符,使用 ]* 有效, 使用  *# 无效 send "touch /home/hadoop/aa.txt\r" expect "]*" send "echo hello world >> /home/hadoop/aa.txt\r" expect "]*" [interact]                  ##人为交互 send "exit\r"               ##退出
    2.配置免密登录并安装JDK
    #!/bin/bash
    #!/usr/bin/expect SERVERS="114.114.114.114"       ##数组以空格分隔,可以为目标ip 或者hostName PASSWORD="yangkun"
    ## 实现免密登录配置的函数
    auto_ssh_copy_id() {    expect -c "set timeout -1;        spawn ssh-copy-id \"-p 2020 $1\";       ## 这里要注意,使用'或\'不可行        expect {            *(yes/no)* {send -- yes\r;exp_continue;}            *password:* {send -- $2\r;exp_continue;}            eof {exit 0;}        }"; } ## 循环执行,配置主机到从节点所有免密
    ssh_copy_id_to_all() {    for SERVER in $SERVERS              ## 取值需要加$    do        auto_ssh_copy_id $SERVER $PASSWORD    done     } ## 调用循环配置函数 ssh_copy_id_to_all ## 批量部署for SERVER in $SERVERSdo    scp install.sh root@$SERVER:/root    ssh root@$SERVER /root/install.sh done
    • 读取文件中的host配置
    让脚本自动读取slaves文件中的机器名来批量安装
    cat slaves | while read host
    do
    echo $host expect -c "set timeout -f spawn ssh-copy-id $host"
    done

    3.批量配置JDK,install.sh

    #!/bin/bash
    BASE_SERVER=master
    BASE_PATH=/home/hadoop/soft
    TARGET_PATH=/usr/local
    JAVA_PATH=$TARGET_PATH/java
    ## 1.判断是否存在文件夹,不存在则创建soft文件夹#
    if [ ! -d "$BASE_PATH" ]; then
       mkdir "$BASE_PATH"
    fi
    ## 2.从指定host拷贝jdk到目标机器上(已经拷贝文件夹) scp -r $BASE_SERVER:$BASE_PATH $BASE_PATH
    ## 2.解压jdk到指定目录
    if [ ! -d "$JAVA_PATH" ]; then sudo -S mkdir -p "$JAVA_PATH"
    fi
    ## 赋予权限 sudo -S chmod -R hadoop:hadoop $JAVA_PATH tar -zxvf $BASE_PATH/jdk1.8.0_121.tar.gz -C $JAVA_PATH
    #### 3.配置环境变量 sudo -S cat>>/etc/profileexport JAVA_HOME=$JAVA_PATH/jdk1.8.0_121 export PATH=\$PATH:\$JAVA_HOME/bin EOF
    • 自动telnet会话
    #!/usr/bin/expect -f
    set ip [lindex $argv 0 ]         
    # 接收第1个参数,作为IP
    set userid [lindex $argv 1 ]     
    # 接收第2个参数,作为userid
    set mypassword [lindex $argv 2 ] 
    # 接收第3个参数,作为密码
    set mycommand [lindex $argv 3 ]  
    # 接收第4个参数,作为命令
    set timeout 10                   
    # 设置超时时间# 向远程服务器请求打开一个telnet会话,并等待服务器询问用户名 spawn telnet $ip    expect "username:"    # 输入用户名,并等待服务器询问密码    send "$userid\r"    expect "password:"    # 输入密码,并等待键入需要运行的命令    send "$mypassword\r"    expect "%"    # 输入预先定好的密码,等待运行结果    send "$mycommand\r"    expect "%"    # 将运行结果存入到变量中,显示出来或者写到磁盘中    set results $expect_out(buffer)    # 退出telnet会话,等待服务器的退出提示EOF    send "exit\r"    expect eof

    4.自动建立FTP会话

    #!/usr/bin/expect -f
    set ip [lindex $argv 0 ]         
    # 接收第1个参数,作为IP
    set userid [lindex $argv 1 ]     
    # 接收第2个参数,作为Userid
    set mypassword [lindex $argv 2 ] 
    # 接收第3个参数,作为密码
    set timeout 10                   
    # 设置超时时间# 向远程服务器请求打开一个FTP会话,并等待服务器询问用户名 spawn ftp $ip    expect "username:"    # 输入用户名,并等待服务器询问密码    send "$userid\r"    expect "password:"    # 输入密码,并等待FTP提示符的出现    send "$mypassword\r"    expect "ftp>"    # 切换到二进制模式,并等待FTP提示符的出现    send "bin\r"    expect "ftp>"    # 关闭ftp的提示符    send "prompt\r"    expect "ftp>"    # 下载所有文件    send "mget *\r"    expect "ftp>"    # 退出此次ftp会话,并等待服务器的退出提示EOF    send "bye\r"    expect eof
    • 自动登录ssh执行命令
    #!/usr/bin/expect
    set IP     [lindex $argv 0] set USER   [lindex $argv 1] set PASSWD [lindex $argv 2] set CMD    [lindex $argv 3] spawn ssh $USER@$IP $CMD expect {    "(yes/no)?" {        send "yes\r"        expect "password:"        send "$PASSWD\r"        }    "password:" {send "$PASSWD\r"}    "* to host" {exit 1}    } expect eof

    5.自动登录ssh

    #!/usr/bin/expect -f  
    set ip [lindex $argv 0 ]         
    # 接收第1个参数,作为IP
    set username [lindex $argv 1 ]   
    # 接收第2个参数,作为username
    set mypassword [lindex $argv 2 ] 
    # 接收第3个参数,作为密码
    set timeout 10                   # 设置超时时间 spawn ssh $username@$ip       # 发送ssh请求 expect {                     
    # 返回信息匹配
    "*yes/no" { send "yes\r"; exp_continue}  # 第一次ssh连接会提示yes/no,继续  
    "*password:" { send "$mypassword\r" }    # 出现密码提示,发送密码   } interact        # 交互模式,用户会停留在远程服务器上面

    6.批量登录ssh服务器执行操作范例,设定增量的for循环

    #!/usr/bin/expect
    for {set i 10} 
    {
    $i set timeout 30  set ssh_user [lindex $argv 0]  spawn ssh -i .ssh/$ssh_user abc$i.com  expect_before "no)?" {  send "yes\r" }  sleep 1  expect "password*"  send "hello\r"  expect "*#"  send "echo hello expect! > /tmp/expect.txt\r"  expect "*#"  send "echo\r" } exit

    7.批量登录ssh并执行命令,foreach语法

    #!/usr/bin/expect
    if {$argc!=2} {    send_user "usage: ./expect ssh_user password\n"    exit } foreach i {11 12} {    set timeout 30    set ssh_user [lindex $argv 0]    set password [lindex $argv 1]    spawn ssh -i .ssh/$ssh_user root@xxx.yy.com    expect_before "no)?" {    send "yes\r" }    sleep 1    expect "Enter passphrase for key*"    send "password\r"    expect "*#"    send "echo hello expect! > /tmp/expect.txt\r"    expect "*#"    send "echo\r" } exit

    8.另一自动ssh范例,从命令行获取服务器IP,foreach语法,expect嵌套

    #!/usr/bin/expect
    # 使用方法: script_name ip1 ip2 ip3 ...set timeout 20 if {$argc "Usage: script IPs"  exit 1 } # 替换你自己的用户名set user "username"
    # 替换你自己的登录密码set password "yourpassword" foreach IP $argv { spawn ssh $user@$IP expect \  "(yes/no)?" {    send "yes\r"    expect "password:?" {      send "$password\r"    }  } "password:?" {    send "$password\r" } expect "\$?"# 替换你要执行的命令 send "last\r" expect "\$?" sleep 10 send "exit\r" expect eof }

    9.批量ssh执行命令,用shell调用tclsh方式、多进程同时执行

    *   tclsh - Simple shell containing Tcl interpreter
    1
    #!/bin/sh
    # -*- tcl -*- \exec tclsh $0 "$@" package require Expect set username [lindex $argv 0] set password [lindex $argv 1] set argv [lrange $argv 2 end] set prompt "(%|#|\\$) $" foreach ip $argv {    spawn ssh -t $username@$ip sh    lappend ids $spawn_id } expect_before -i ids eof {    set index [lsearch $ids $expect_out(spawn_id)]    set ids [lreplace $ids $index $index]    if [llength $ids] exp_continue } expect -i ids "(yes/no)\\?" {    send -i $expect_out(spawn_id) yes\r    exp_continue } -i ids "Enter passphrase for key" {    send -i $expect_out(spawn_id) \r    exp_continue } -i ids "assword:" {    send -i $expect_out(spawn_id) $password\r    exp_continue } -i ids -re $prompt {    set spawn_id $expect_out(spawn_id)    send "echo hello; exit\r"    exp_continue } timeout {    exit 1 }

    10.ssh登录过程常规提示文字

    The authenticity of host '192.168.17.35 (192.168.17.35)' can't be established.
    RSA key fingerprint is 25:e8:4c:89:a3:b2:06:ee:de:66:c7:7e:1b:fa:1c:c5.
    Are you sure you want to continue connecting (yes/no)?
    
    
    Warning: Permanently added '192.168.17.35' (RSA) to the list of known hosts.
    Enter passphrase for key '/data/key/my_dsa':
    
    
    Last login: Sun Jan 26 13:39:37 2014 from 192.168.11.143
    [root@master003 ~]#
    
    
    root@192.168.16.90's password:
    
    
    Last login: Thu Jan 23 17:50:43 2014 from 192.168.11.102
    [root@lvsmaster ~]#

    11.ssh自动登录expect脚本:ssh.expect

    #!/usr/bin/expect -f
    # Auther:YuanXing
    # Update:2014-02-08if {$argc "Usage:\n  $argv0 IPaddr User Passwd Port Passphrase\n"    puts stderr "argv error!\n"    sleep 1    exit 1 } set ip         [lindex $argv 0 ] set user       [lindex $argv 1 ] set passwd     [lindex $argv 2 ] set port       [lindex $argv 3 ] set passphrase [lindex $argv 4 ] set timeout 6 if {$port == ""} {    set port 22 } #send_user "IP:$ip,User:$user,Passwd:$passwd,Port:$port,Passphrase:$passphrase" spawn ssh -p $port $user@$ip expect_before "(yes/no)\\?" {    send "yes\r"} expect \ "Enter passphrase for key*" {    send "$passphrase\r"    exp_continue } " password:?" {    send "$passwd\r"    exp_continue } "*\[#\\\$]" {    interact } "* to host" {    send_user "Connect faild!"    exit 2 } timeout {    send_user "Connect timeout!"    exit 2 } eof {    send_user "Lost connect!"    exit }

    12.Mikrotik backup script using ssh and expect

    #!/bin/bash
    # TAG: mikrotik, ssh, expect, lftp BACKUP_DIR="/var/backups" HOSTNAME="192.168.88.1" PORT="22" USER="admin" PASS="123456" TMP=$(mktemp) TODAY=$(date +%F) FILENAME="$HOSTNAME-$TODAY" PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin"# create expect script cat > $TMP #exp_internal 1 # Uncomment for debug set timeout -1 spawn ssh -p$PORT $USER@$HOSTNAME match_max 100000 expect -exact "password:" send -- "$PASS\r" sleep 1 expect " > " send -- "/export file=$FILENAME\r" expect " > " send -- "/system backup save name=$FILENAME\r" expect " > " send -- "quit\r" expect eof EOF # run expect script#cat $TMP # Uncomment for debug expect -f $TMP# remove expect script rm $TMP# download and remove backup files# "xfer:clobber on" means overwrite existing filescd ${BACKUP_DIR}echo "  set xfer:clobber on  get ${FILENAME}.rsc  rm ${FILENAME}.rsc  get ${FILENAME}.backup  rm ${FILENAME}.backup" | lftp -u $USER,$PASS $HOSTNAME

    有一些需要自动输入密码的场景,可以用expect

    自动与交互式程序会话

    脚本

    #!/usr/bin/expect -f

    argv:接收参数

    argc:参数个数

    argv0:脚本名

    选项

    -c "cmd":指定在执行脚本之前执行的命令,这些命令最好用双引号括起,防止被shell分开解释,可以反复使用-c

    -d:输出调试信息,报告expect和interact等命令执行时的内部行为,脚本开头写"exp_internal 1"也可以达到同样的效果

    -D:交互式调试器

    -f:指定命令文件

    -i:交互式提示输入命令

    --:划定选项尾,如脚本中写 #! /usr/bin/expect - ,则任何命令行的选项都会被解释为参数,被argv接收

    命令

    setfile “xxx” 设置参数file的值为"xxx"

    close:关闭与当前进程的链接

    expect和interact都可以检查到进程的退出,隐含执行一个close命令,如果用exec kill pid方式杀进程,则需要显示调用一次close指令

    -slave 同时关闭从属进程

    -onexec 0 保持spawn_id 开启,1关闭当前的spawn_id

    -i 指定关闭的spawn_id

    debug:调试

    now立即启动调试器,0停止,1启动

    disconnect:从终端断开与克隆进程的连接,克隆进程会在后台作为独立进程组继续运行,IO被重定向到/dev/null

    send_user "password?\ "

    expect_user -re "(.*)\n"

    for {} 1 {} {

    if [fork]!=0 {sleep 3600;continue}

    disconnect #克隆进程继续运行

    spawn priv_prog

    expect Password:

    send "$expect_out(1,string)\r"

    . . .

    exit

    }

    Exp_continue[-continue_timer]

    这个命令可以使expect继续执行而不是正常的返回.默认情况下,exp_continue会重高超时时钟,-continue_timer选项会阻止时钟重新计数(连续计数).

    Exp_internal [-f file] value

    如果是value非零的话,使接下来的命令将调试信息输出到Expect和标准错误输出.如果是0的话,输出的信息将会被屏蔽.调试信息包括收到的每条信息和每次尝试用当前输出与脚本中的模式相匹配的信息.如果设置了输出文件,那么正常的和调试的信息都会被写到这个文件当中.(忽略上面value选项的值).任何之前打开的调试输出文件将会被关闭.-info选项使exp_internal返回最近关于non-info参数的描述

    Exp_open [args] [-I spawn_id]

    它返回对应于原始spawn id的文件描述符.这样这个文件描述符就可以被使用了,就好像这个文件是被Tcl的open指令打开的一样.(这个spawn id将不再使用,wait指令将不能用在这个进程.).-leaveopen选项使spawn id保持打开,以便供Expect命令使用

    Exp_pid [-i spawn_id]

    它将返回对应于当前被跟踪进程的ID.如果使用-i选项,将返回对应于指定的spawn id的进程ID.

    Exp_send:send别名

    Exp_send_error:它是Send_error

    Exp_send_log:Send_log

    Exp_send_tty:Send_tty

    Exp_send_user:Send_user

    Exp_version [[-exit] version]

    它用于确保脚本程序与当前的Expect兼容。在没有参数的情况下,返回当前Expect的版本.这个版本就会编译到脚本中.如果你确切的知道你的脚本程序不需要最新版本的特性,可以指定一个以前的版本

    expect_tty [expect_args ],输入是一个tty

    expect_user [expect_args],输入是stdin

    expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]

    等待被监控进程的输出,如果匹配到指定输出字符串、遇到文件尾、或超时时,则执行对应的body体,如果body是空的,将被忽略

    -nocase 匹配时不区分大小写

    -timeout:选项使得Expect使用选项后面的数值做为超时时间,而不是timeout变量中设置的时间

    expect_befor模式,在所有匹配之前隐含调用

    expect_after模式,在所有匹配之后隐含调用

    expect {

    busy {puts busy\n ; exp_continue} # 输出值有busy执行{}里面的语句

    failed abort # 输出有failed,执行abort,abort是预定义的一个函数

    "invalid password" abort #输出字符串中间有空格,需要用双引号括起来

    -re "failed|invalid password" abort #使用正则表达式

    -ex "failed|invalid *password" abort #精准正则,不对* ^等转义

    -i $proc2 busy {puts busy\n ; exp_continue} #匹配$proc2进程的输出,默认是当前进程的输出

    -i $proc3 # 匹配到执行XXX

    -i $proc4 # 匹配到执行XXX

    any_spawn_id XXX

    timeout abort #超时时触发

    full_buffer abort #输出的值超过最大的match_max设置的值是触发

    null #输出ascii 0时触发

    connected

    }

    匹配时,任何输出都会被保存到expect_out缓冲区中,匹配到的9个字串分别被保存在expect_out(1, string) ~ expect_out(9, string),如果在模式前面使用了 -indeces 选项,则这9个字串的起始位置和结束位置保存在expect_out(X, start)和expect(X, end)中,X∈[0, 9]。expect(0,*)是匹配到的整个字符串,下面三条语句等效

    expect "cd"

    Set expect_out(0,string) cd

    Set expect_out(buffer) abcd

    -i选项还可以定义一个全局变量,里面存储着spawn_id列.当变量内容发生变化时,它会被重新读取.这样就可以在程序执行的时候改变I/O源.以这种方式提供的spawn_id被称为”indirect spawn_id”

    Fork

    复制一个进程,返回新进程ID,失败返回-1

    interact [string1 body1] ... [stringn [bodyn]]

    将控制权给用户,根据用户的输入,触发相应的动作

    set CTRLZ \032

    interact {

    -reset $CTRLZ {exec kill -STOP [pid]} # 按下ctrl+z触发

    \001 {send_user "you typed a control-A\n"; # 发送一个字符串到终端

    send "\001"

    }

    $ {send_user "The date is [exec date]."}

    \003 exit

    foo {send_user "bar"} # 用户输入foo时触发

    ~~

    }

    send:发送字符串给当前进程

    send_user:发送字符串到标准输出

    send_error:发送字符串到标准错误

    send_log:发送字符串到日志文件

    send_tty:发送字符串到tty

    sleep seconds:休眠

    spawn [args] program [args]

    创建一个执行program命令的进程,这个进程的三个标准IO都被重定向到expect,

    spawn su - ftomcat -c "tar -xzf /tmp/ftomcat.tgz . 1>/dev/null 2>/dev/null"

    expect "Password"

    send "ftomcat\r"

    expect eof

    exit

    _close.pre_expect
    after
    append
    apply
    array
    auto_execok
    auto_import
    auto_load
    auto_load_index
    auto_qualify
    binary
    break
    case
    catch
    cd
    chan
    clock
    close
    close_on_eof
    concat
    continue
    coroutine
    debug
    dict
    disconnect
    encoding
    eof
    error
    eval
    exec
    exit
    exp_close
    exp_close_on_eof
    exp_configure
    exp_continue
    exp_debug
    exp_disconnect
    exp_exit
    exp_fork
    exp_getpid
    exp_inter_return
    exp_interact
    exp_internal
    exp_interpreter
    exp_log_file
    exp_log_user
    exp_match_max
    exp_open
    exp_overlay
    exp_parity
    exp_pid
    exp_remove_nulls
    exp_send
    exp_send_error
    exp_send_log
    exp_send_tty
    exp_send_user
    exp_sleep
    exp_spawn
    exp_strace
    exp_stty
    exp_system
    exp_timestamp
    exp_trap
    exp_version
    exp_wait
    expect
    expect_after
    expect_background
    expect_before
    expect_tty
    expect_user
    expr
    fblocked
    fconfigure
    fcopy
    file
    fileevent
    flush
    for
    foreach
    fork
    format
    getpid
    gets
    glob
    global
    history
    if
    incr
    info
    inter_return
    interact
    interp
    interpreter
    join
    lappend
    lassign
    lindex
    linsert
    list
    llength
    lmap
    load
    log_file
    log_user
    lrange
    lrepeat
    lreplace
    lreverse
    lsearch
    lset
    lsort
    match_max
    namespace
    open
    overlay
    package
    parity
    pid
    proc
    prompt1
    prompt2
    puts
    pwd
    read
    regexp
    regsub
    remove_nulls
    rename
    return
    scan
    seek
    send
    send_error
    send_log
    send_tty
    send_user
    set
    sleep
    socket
    source
    spawn
    split
    strace
    string
    stty
    subst
    switch
    system
    tailcall
    tclLog
    tell
    throw
    time
    timestamp
    trace
    trap
    try
    unknown
    unload
    unset
    update
    uplevel
    upvar
    variable
    vwait
    wait
    while
    yield
    yieldto
    zlib

    ============ End

  • 相关阅读:
    使用npoi做excel导出真心方便
    JAVA泛型(代码级解释)
    数据库战略高度解析(4) JDBCODBC
    [Python] 函数lambda(), filter(), map(), reduce()
    JEECG引领新的开发模式,让开发更加专注于业务!
    Parse 是什么
    Openflashchart及代理类设计介绍
    数据库战略高度解析(3) ODBC
    java 中paint .repaint.update
    svn利用钩子脚本功能实现代码同步到web目录
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/16546562.html
Copyright © 2020-2023  润新知