Mac 自动化执行脚本 Expect

来源:互联网 发布:22岁秋冬水乳推荐 知乎 编辑:程序博客网 时间:2024/04/27 23:39

环境

Mac

安装expect

brew install expect

使用

传参

# 表示获取执行脚本命名空格后第一个参数set user [lindex $argv 0]

实际应用例子

ssh自动登录

#!/usr/bin/expectset user root  set ipaddress 120.76.xx.xxset passwd xxxset timeout 30spawn ssh $user@$ipaddressexpect {    "*password:" { send "$passwd\r" }    "yes/no" { send "yes\r";exp_continue }}interact

#!/usr/bin/expect -fspawn ssh -p 22 developer@120.76.103.192 expect "*password:"send "Sound318\r"interact #操作完成

scp传输例子

#!/usr/bin/expect set user root  set user host  set pwd 123pwdset from_path 120.76.xx.xxset to_path xxxspawn scp $from_path $user@$host:$to_pathexpect {    "*password:" { send "$pwd\n" }}interact

录制脚本

可以使用提供的脚本进行录制

vim autoexpect.exp

#!/usr/bin/expect --# Name: autoexpect - generate an Expect script from watching a session## Description:## Given a program name, autoexpect will run that program.  Otherwise# autoexpect will start a shell.  Interact as desired.  When done, exit# the program or shell.  Autoexpect will create a script that reproduces# your interactions.  By default, the script is named script.exp.# See the man page for more info.## Author: Don Libes, NIST# Date: June 30 1995# Version: 1.4bset filename "script.exp"set verbose 1set conservative 0set promptmode 0set option_keys ""proc check_for_following {type} {    if ![llength [uplevel set argv]] {        puts "autoexpect: [uplevel set flag] requires following $type"        exit 1    }}    while {[llength $argv]>0} {    set flag [lindex $argv 0]    if 0==[regexp "^-" $flag] break    set argv [lrange $argv 1 end]    switch -- $flag \      "-c" {        set conservative 1    } "-C" {        check_for_following character        lappend option_keys [lindex $argv 0] ctoggle        set argv [lrange $argv 1 end]    } "-p" {        set promptmode 1    } "-P" {        check_for_following character        lappend option_keys [lindex $argv 0] ptoggle        set argv [lrange $argv 1 end]    } "-Q" {        check_for_following character        lappend option_keys [lindex $argv 0] quote        set argv [lrange $argv 1 end]    } "-f" {        check_for_following filename        set filename [lindex $argv 0]        set argv [lrange $argv 1 end]    } "-quiet" {        set verbose 0    } default {        break    }}############################################################## Variables    Descriptions############################################################## userbuf    buffered characters from user# procbuf    buffered characters from process# lastkey    last key pressed by user#        if undefined, last key came from process# echoing    if the process is echoing############################################################## Handle a character that came from user input (i.e., the keyboard)proc input {c} {    global userbuf lastkey    send -- $c    append userbuf $lastkey    set lastkey $c}# Handle a null character from the keyboardproc input_null {} {    global lastkey userbuf procbuf echoing    send -null    if {$lastkey == ""} {        if $echoing {            sendcmd "$userbuf"        }        if {$procbuf != ""} {            expcmd "$procbuf"        }    } else {        sendcmd "$userbuf"        if $echoing {            expcmd "$procbuf"            sendcmd "$lastkey"        }                }    cmd "send -null"    set userbuf ""    set procbuf ""    set lastkey ""    set echoing 0}# Handle a character that came from the processproc output {s} {    global lastkey procbuf userbuf echoing    send_user -raw -- $s    if {$lastkey == ""} {        if !$echoing {            append procbuf $s        } else {            sendcmd "$userbuf"            expcmd "$procbuf"            set echoing 0            set userbuf ""            set procbuf $s        }        return    }    regexp (.)(.*) $s dummy c tail    if {$c == $lastkey} {        if $echoing {            append userbuf $lastkey            set lastkey ""        } else {            if {$procbuf != ""} {                expcmd "$procbuf"                set procbuf ""            }            set echoing 1        }        append procbuf $s        if [string length $tail] {            sendcmd "$userbuf$lastkey"            set userbuf ""            set lastkey ""            set echoing 0        }    } else {        if !$echoing {            expcmd "$procbuf"        }        sendcmd "$userbuf$lastkey"        set procbuf $s        set userbuf ""        set lastkey ""        set echoing 0    }}# rewrite raw strings so that can appear as source code but still reproduce# themselves.proc expand {s} {    regsub -all "\\\\" $s "\\\\\\\\" s    regsub -all "\r" $s "\\r"  s    regsub -all "\"" $s "\\\"" s    regsub -all "\\\[" $s "\\\[" s    regsub -all "\\\]" $s "\\\]" s    regsub -all "\\\$" $s "\\\$" s    return $s}# generate an expect commandproc expcmd {s} {    global promptmode    if $promptmode {        regexp ".*\[\r\n]+(.*)" $s dummy s    }    cmd "expect -exact \"[expand $s]\""}# generate a send commandproc sendcmd {s} {    global send_style conservative    if {$conservative} {        cmd "sleep .1"    }    cmd "send$send_style -- \"[expand $s]\""}# generate any commandproc cmd {s} {    global fd    puts $fd "$s"}proc verbose_send_user {s} {    global verbose    if $verbose {        send_user -- $s    }}proc ctoggle {} {    global conservative send_style    if $conservative {        cmd "# conservative mode off - adding no delays"        verbose_send_user "conservative mode off\n"        set conservative 0        set send_style ""    } else {        cmd "# prompt mode on - adding delays"        verbose_send_user "conservative mode on\n"        set conservative 1        set send_style " -s"    }}proc ptoggle {} {    global promptmode    if $promptmode {        cmd "# prompt mode off - now looking for complete output"        verbose_send_user "prompt mode off\n"        set promptmode 0    } else {        cmd "# prompt mode on - now looking only for prompts"        verbose_send_user "prompt mode on\n"        set promptmode 1    }}# quote the next character from the userproc quote {} {    expect_user -re .    send -- $expect_out(buffer)}if [catch {set fd [open $filename w]} msg] {    puts $msg    exit}exec chmod +x $filenameverbose_send_user "autoexpect started, file is $filename\n"# calculate a reasonable #! lineset expectpath /usr/local/bin        ;# prepare defaultforeach dir [split $env(PATH) :] {    ;# now look for real location    if [file executable $dir/expect] {        set expectpath $dir        break    }}cmd "#![set expectpath]/expect -f## This Expect script was generated by autoexpect on [timestamp -format %c]# Expect and autoexpect were both written by Don Libes, NIST."cmd {## Note that autoexpect does not guarantee a working script.  It# necessarily has to guess about certain things.  Two reasons a script# might fail are:## 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,# etc.) and devices discard or ignore keystrokes that arrive "too# quickly" after prompts.  If you find your new script hanging up at# one spot, try adding a short sleep just before the previous send.# Setting "force_conservative" to 1 (see below) makes Expect do this# automatically - pausing briefly before sending each character.  This# pacifies every program I know of.  The -c flag makes the script do# this in the first place.  The -C flag allows you to define a# character to toggle this mode off and on.set force_conservative 0  ;# set to 1 to force conservative mode even if              ;# script wasn't run conservatively originallyif {$force_conservative} {    set send_slow {1 .1}    proc send {ignore arg} {        sleep .1        exp_send -s -- $arg    }}## 2) differing output - Some programs produce different output each time# they run.  The "date" command is an obvious example.  Another is# ftp, if it produces throughput statistics at the end of a file# transfer.  If this causes a problem, delete these patterns or replace# them with wildcards.  An alternative is to use the -p flag (for# "prompt") which makes Expect only look for the last line of output# (i.e., the prompt).  The -P flag allows you to define a character to# toggle this mode off and on.## Read the man page for more info.## -Don}cmd "set timeout -1"if $conservative {    set send_style " -s"    cmd "set send_slow {1 .1}"} else {    set send_style ""}if [llength $argv]>0 {    eval spawn -noecho $argv    cmd "spawn $argv"} else {    spawn -noecho $env(SHELL)    cmd "spawn \$env(SHELL)"}cmd "match_max 100000"set lastkey ""set procbuf ""set userbuf ""set echoing 0remove_nulls 0eval interact $option_keys {    -re . {        input $interact_out(0,string)    } null {        input_null    } \    -o \    -re .+ {        output $interact_out(0,string)    } eof {        cmd "expect eof"        return    } null {    }}close $fdverbose_send_user "autoexpect done, file is $filename\n"

执行

# exit退出,会在当前目录生成一个script.exp文件expect autoexpect.exp -p

自己使用例子

打包、上传dev、备份、重启

#!/usr/local/bin/expect -f## Auto pack, scp, restart app by expect.## Use example:#   ./pack_dev.sh developer 192.140.12.2 pwd /java/workspace-idea-soundbus/bet-game-service /java/workspace-idea-soundbus/bet-game-service/bet-game/target/bet-game.jar /home/developer/sunbar/bet-game-service/bet-game-$(date +'%Y%m%d').jar bet-game /home/developer/sunbar/bet-game-service## Init env(mac os):#   brew install expect# # Created by suzhida on 2017-08-06 14:47:11set service_user [lindex $argv 0]set service_ip [lindex $argv 1]set service_pwd [lindex $argv 2]set pack_path [lindex $argv 3]set scp_source_path [lindex $argv 4]set scp_to_path [lindex $argv 5]set app_name [lindex $argv 6]set service_app_path [lindex $argv 7]set timeout -1# bash shellspawn $env(SHELL)match_max 100000expect -exact ""# packsend -- "cd $pack_path\r"expect -exact "cd $pack_path"send -- "mvn clean install -Dskip.unit.tests=true\r"expect -exact "mvn clean install -Dskip.unit.tests=true"# scp send -- "scp $scp_source_path $service_user@$service_ip:$scp_to_path\r"expect -exact "$service_user@$service_ip's password: "send -- "$service_pwd\r"expect -exact ""# restart appsend -- "ssh -p 22 $service_user@$service_ip\r"expect -exact "$service_user@$service_ip's password: "send -- "$service_pwd\r"expect -exact ""send -- "cd $service_app_path\r"expect -exact ""send -- "ln -sf $service_app_path-\$(date +'%Y%m%d').jar $service_app_path-current.jar\r"expect -exact ""send -- "./boot.sh\r"expect -exact ""send -- "tailf log/spring.log\r"expect -exact ""# done interact

1) 维基百科介绍
2) 官网
3) 使用expect工具ssh登录远程服务器并执行命令操作
4) expect用法
5) linux expect详解

原创粉丝点击