expect詳解

1. expect是基於tcl演變而來的,所以很多語法和tcl類似,基本的語法如下所示:
1.1 首行加上/usr/bin/expect
1.2 spawn: 後面加上需要執行的shell命令,比如說spawn sudo touch testfile
1.3 expect: 只有spawn執行的命令結果纔會被expect捕捉到,因爲spawn會啓動一個進程,只有這個進程的相關信息纔會被捕捉到,主要包括:標準輸入的提示信息eof和timeout

1.4 send和send_user:send會將expect腳本中需要的信息發送給spawn啓動的那個進程,而send_user只是回顯用戶發出的信息,類似於shell中的echo而已。

1.5 puts同send_user 都是打印信息

1.6 expect中的算數運算 set i [expr {i+1}]  //等價於遞增運算符 incr i

1.7 if 語法:

注意if while for 等語句中第一行必須爲 if空格{}空格{ //{必須出現在該行

===if的寫法
    if { $sync_flag == "true" } {

            puts "Sync start at [clock format [clock seconds]]"

            catch {eval exec ${TOOL_HOME}/bin/${sync_cmd} ${sync_parm} } output
            puts $output
            if { $output eq "SYNC complete!" } {
                    puts "SYNC complete!"
            } else {
                    puts "SYNC error!"
                    exit 1
            }

            puts "Sync end at [clock format [clock seconds]]"
    }

1.8 for/while語法:

==for/while循環寫法


    #!/usr/bin/expect --
    #                  http://bbs.chinaunix.net/thread-2301733-1-1.html
    # for Bob testing
    #
    puts "---1---"
    for {set i 0} {$i < 10} {incr i} {
        puts "I inside first loop: $i"
    }

    puts "---2---"
    for {set i 3} {$i < 2} {incr i} {
        puts "I inside second loop: $i"
    }

    puts "---3---"
    puts "Start"
    set i 0
    while {$i < 10} {
        puts "I inside third loop: $i"
        incr i
        puts "I after incr: $i"
    }

    set i 0
    incr i
    puts "---4---"
    puts "$i"
    # This is equivalent to:
    set i [expr {$i + 1}]    #expect裏的加減法
    puts "---5---"
    puts "$i"

運行:

    [15:33:09-Bob@hzling08:~/test/tcl]-(1110)No.109->$ ./tclfor.test
    ---1---
    I inside first loop: 0
    I inside first loop: 1
    I inside first loop: 2
    I inside first loop: 3
    I inside first loop: 4
    I inside first loop: 5
    I inside first loop: 6
    I inside first loop: 7
    I inside first loop: 8
    I inside first loop: 9
    ---2---
    ---3---
    Start
    I inside third loop: 0
    I after incr: 1
    I inside third loop: 1
    I after incr: 2
    I inside third loop: 2
    I after incr: 3
    I inside third loop: 3
    I after incr: 4
    I inside third loop: 4
    I after incr: 5
    I inside third loop: 5
    I after incr: 6
    I inside third loop: 6
    I after incr: 7
    I inside third loop: 7
    I after incr: 8
    I inside third loop: 8
    I after incr: 9
    I inside third loop: 9
    I after incr: 10
    ---4---
    1
    ---5---
    2
1.9 匹配正則 expect -re "\\\[(.*)]" //其中[在expect shell 正則中都有特殊意義,因此要\三次

     其中()中間的內容爲匹配的內容,取出方法爲:$expect_out(1,string)

在一個正則表達時中,可以在()中包含若干個部分並通過expect_out數組訪問它們。各個部分在表達式中從左到右進行編碼,從1開始(0包含有整個匹配輸出)。()可能會出現嵌套情況,這這種情況下編碼從最內層到最外層來進行的

1.10 取出腳本參數方法  

set file [lindex $argv 0] //獲取第一個參數

set num $argc //獲取參數個數、

1.11 send 發送完命令之後都需要跟上一個回車"\n"

1.12 若要expect腳本執行完後保留在登陸機器則最後加一句 interact

2. expect 使用方法

2.1 使用“-c”選項,從命令行執行expect腳本

expect可以讓你使用“-c”選項,直接在命令行中執行它,如下所示:

$ expect -c 'expect "\n" {send "pressed enter\n"}

pressed enter
$
	如果你執行了上面的腳本,它會等待輸入換行符(\n)。按“enter”鍵以後,它會打印出“pressed enter”這個消息,然後退出。
2.2 使用“-i”選項交互地執行expect腳本
	使用“-i”選項,可以通過來自於標準輸入的讀命令來交互地執行expect腳本。如下所示:
$ expect -i arg1 arg2 arg3
expect1.1>set argv
arg1 arg2 arg3
expect1.2>
	正常情況下,當你執行上面的expect命令的時候(沒有“-i”選項),它會把arg1當成腳本的文件名,所以“-i”選項可以讓腳本把多個參數當成一個連續的列表。
	當你執行帶有“-c”選項的expect腳本的時候,這個選項是十分有用的。因爲默認情況下,expect是交互地執行的。
2.3 當執行expect腳本的時候,輸出調試信息
	當你用“-d”選項執行代碼的時候,你可以輸出診斷的信息。如下所示:
$ cat sample.exp
# !/usr/bin/expect -f
expect "\n";
send "pressed enter";


$ expect -d sample.exp
expect version 5.43.0
argv[0] = expect  argv[1] = -d  argv[2] = sample.exp
set argc 0
set argv0 "sample.exp"
set argv ""
executing commands from command file sample.exp expect: does "" (spawn_id exp0) match glob pattern "\n"? no expect: does "\n" (spawn_id exp0) match glob pattern "\n"? yes expect: set expect_out(0,string) "\n" expect: set expect_out(spawn_id) "exp0" expect: set expect_out(buffer) "\n" send: sending "pressed enter" to { exp0 pressed enter}
2.4 使用“-D”選項啓動expect調試器
	“-D”選項用於啓動調試器,它只接受一個布爾值的參數。這個參數表示提示器必須馬上啓動,還是隻是初始化調試器,以後再使用它。
$ expect -D 1 script
	“-D”選項左邊的選項會在調試器啓動以前被處理。然後,在調試器啓動以後,剩下的命令纔會被執行。
$ expect -c 'set timeout 10' -D 1 -c 'set a 1'
1: set a 1
dbg1.0>
2.5 逐行地執行expect腳本
	通常,expect會在執行腳本之前,把整個腳本都讀入到內存中。“-b”選項可以讓expect一次只讀取腳本中的一行。當你沒有寫完整個腳本的時候,這是十分有用的,expect可以開始執行這個不完整的腳本,並且,它可以避免把腳本寫入到臨時文件中。
$ expect -b
2.6 讓expect不解釋命令行參數
	你可以使用標識符讓expect不解釋命令行參數。
	你可以像下面這樣的讀入命令行參數:
$ cat  print_cmdline_args.exp
#!/usr/bin/expect
puts 'argv0 : [lindex $argv 0]';
puts 'argv1 : [lindex $argv 1]';

當執行上面的腳本的時候,會跳過命令行選項,它們會被當成參數(而不是expect選項),如下所示:

$ expect print_cmdline_args.exp -d -c
argv0 : -d
argv1 : -c
3. #!/usr/bin/expect 和 #!/usr/bin/expect -f 區別:

前者會忽略掉 -c 選項 比如腳本文件k.exp:

#!/usr/bin/expect 
puts "aaa"
在命令行執行 ./k.exp -c "bbb" 

後者會輸出:

bbb

aaa

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章