expect使用技巧



1) 獲取命令行參數,例如通過./abc.exp a1 a2執行expect腳本

set 變量名1 [lindex $argv 0] 獲取第1個參數a1

set 變量名2 [lindex $argv 1] 獲取第2個參數a2

 

2)函數中使用外部變量

例如在函數外部定義了變量va:  set va "", 現在現在某個函數中使用,需要通過全局范圍限定符進行引用,即$::va,如果進行變量修改,可以使用 set ::va xxx

 

3) 在expect中執行shell語句

例如:

exec sh -c {

if [ -f "$HOME/.ssh/known_hosts" ]
then
    >$HOME/.ssh/known_hosts
fi
}

 

4) 獲取spawn id

例如:

spawn ssh -l $::LAB_USER $IP
set MY_SPAWN_ID $spawn_id

 

5)  expect以及send指定spawn id

如果只是簡單的一個spawn遠端連接,隨后進行expect/send語句,無需指定spawn id, 有時比較復雜,比如有多個spawn id,那么需要使用 -i 指明具體哪一個,例如:

expect {
        -i $::MY_SPAWN_ID
        "/home/xxx:" {
            send -i $::MY_SPAWN_ID "YOUR SHELL CMD HERE\r";
        }
        timeout { puts "timeout for xxx"; exit }
    }

 

6) 獲取send命令執行結果

可以通過$expect_out(buffer) 獲取上一次send命令以后的遠端輸出結果,此變量必須在send以后的下一個expect { }語句中使用才有效。上一個send最好也是在某個expect{ }中執行,否則可能不起作用。例如:

expect {
        "#" {
            send  "ps -ef|grep my_app|grep -v grep\r"; (grep -v表示取反,去掉不想要的信息,因為會有一條多余的grep命令在grep結果中顯示出來)
        }
        timeout { puts "timeout for xxx"; exit }
    }
expect {
        "#" {
            puts "Got response: $expect_out(buffer)";
        }
        timeout { puts "timeout for xxx"; exit }
    }

 

7) 清空expect_out結果

在expect { }語句內部執行unset expect_out(buffer);

 

8) 正則匹配

例如:

expect {

        -i $::MY_SPAWN_ID
        "#" {
            send  -i  $::MY_SPAWN_ID "ps -ef|grep my_app|grep -v grep\r";  
        }
        timeout { puts "timeout for xxx"; exit }
    }

假設執行send語句以后的遠端輸出如下:

root      4608  3351  0 13:45 ?        00:00:06 my_app --io 393228

root      5490  3351  2 13:46 ?        00:00:18 my_app --io 360459

現在先獲取最后一列的393228與360459,那么可以通過以下正則獲取:

(注意,下面代碼里的中括號【和】需要使用英文的中括號 [ 和 ],這里用中文是因為CSDN會把英文轉義搞錯,僅僅為了顯示)

expect {
        -i $::MY_SPAWN_ID
        -re "(my_app --io\\s+)(\【0-9\】+)" {
            puts "Got my_app process: $expect_out(2,string)";  (此時會輸出393228,如果是$expect_out(0,string)那么將輸出my_app --io 393228)
            unset expect_out(buffer);
        }
        timeout { puts "timeout for KEEP_1_PROCESS"; exit }
    }
    expect {
        -i $::MY_SPAWN_ID
        -re "(my_app --io\\s+)(\【0-9\】+)" {
            puts "Got my_app process: $expect_out(2,string)"; (此時會輸出360459)
            send -i $::MY_SPAWN_ID "\r\n";
        }
        timeout { puts "No more $:APP found, continue" }
    }

 

其中可以將正則表達式用括號進行分組,從而獲取想要的字段,比如上面用了兩個括號組織,通過$expect_out(2,string)可以獲取想要的字段。

不管用不用括號分組,都可以通過$expect_out(0,string)獲得完全匹配的output

 

9) 發送Ctrl-C
如果想向遠端發送Ctrl-C結束遠端進程,可以通過send "\003" 實現。

10) expect/shell互相使用彼此變量
如果是在shell中啟動了expect腳本,現在想在expect中使用shell里的變量,可以有兩種方法:
首先在shell中進行變量export, 例如export a=1, 然后在expect中通過 $::env(a) 引用,例如set a_exp $::env(a)
也可以通過執行子shell調用,例如: set a [exec sh -c {echo $a}]


如果是在expect里面執行shell,並且想在shell里面使用expect的變量,需要在expect里面設置環境變量:

例如:set ::env(LAB) my_lab

那么在shell語句里面可以通過$LAB引用。

11) 寫入文件操作
首先打開文件流,然后寫入內容,最后關閉文件流

set tmp_file [open $::TMP_OUT a+]

expect {
... ...
puts $tmp_file $expect_out(buffer);
unset expect_out(buffer)
}
expect {
... ...
puts $tmp_file $expect_out(buffer);
unset expect_out(buffer)
}

close $tmp_file

12) expect 交互或者退出
如果是交互,那么執行interact 或者加上-i spawn的id
如果是結束,那么執行send "exit\r"以后 expect eof,此時會等待expect進程結束。
如果想快速退出而不等待,那么可以在執行完send "exit\r"以后wait -nowait 立即退出。

13) 獲取當前時間
set current_time [clock format [clock seconds] -format "%Y-%m-%d,%H:%M:%S"]


14) scp 文件傳輸

比如:

spawn scp $YOUR_LOGIN@$YOUR_SERVER:$FILE .

expect {
    "password:" {
        gets stdin PASSWD

        send "$PASSWD\r"

        puts "This may take a while, please wait ......"

    }
    timeout { puts "timeout for login "; exit }
}
expect {
    "No such file or directory" {
        puts "The file $FILE not exists, please have a check"
        exit
    }

}

expect eof

傳輸一個大文件,腳本最后通過expect eof由於expect eof的超時時間很短,默認10秒,因此很可能導致文件傳輸不完整,解決方法是:將expect eof改成 expect -timeout -1 eof
————————————————
版權聲明:本文為CSDN博主「taoyuanforrest」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/just_lion/article/details/80109764


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM