一、安裝與基本概念
Expect是一個自動交互式任務的工具,可以像我們在終端上手動輸入命令一樣操作,支持模擬鍵盤輸入及獲取輸出等等。使用Expect可以方便地實現自動化的交互任務,如自動登錄、自動發郵件等等。
Expect本身可以說是一個語言,是基於Tcl語言的,安裝之前需要先安裝Tcl。
sudo apt-get install tcl
安裝完成之後再安裝Expect:
sudo apt-get install expect
使用Expect的第一步,就是要讓腳本知道我們需要交互的目標。這個目標可以是一個腳本,也可以是一個應用程序。
#!/usr/bin/expect
spawn bash
interact
在這個腳本里,我們使用spawn命令讓腳本知道要和哪個程序進行交互,這裡使用了bash程序。而後面的interact命令,就告訴腳本讓用戶來控制後續的操作。
二、使用spawn命令
Spawn命令是Expect中最常用的命令之一,它的作用是啟動一個新的進程,並且讓你控制這個新進程。
下面是spawn命令的使用方式:
spawn command [args ...]
參數command表示要啟動的程序,[args …]表示可選的參數。例如:
#!/usr/bin/expect
spawn ssh user@example.com
expect "password: "
send "mypassword\r"
interact
在這個腳本里,我們使用spawn命令啟動一個ssh進程並連接到遠程主機。接下來,在expect “password: “後,使用send命令模擬鍵盤輸入,輸入密碼並回車。最後使用interact命令交還控制權給用戶。
三、使用expect命令
Expect命令用於指定腳本等待哪個字符串出現,允許腳本在等待期間執行其他任務,如等待輸入、循環、條件判斷等等。
下面是expect命令的使用方式:
expect pattern1 {action1} pattern2 {action2} ...
pattern表示需要等待的字符串,可以使用單引號或雙引號。action表示待執行的操作,例如模擬鍵盤輸入、打印輸出等等。
例如,以下腳本將模擬遠程連接,並等待遠程主機的輸出結果:
#!/usr/bin/expect
spawn ssh user@192.168.1.1
expect "password:"
send "mypassword\r"
expect "$ "
send "ls\r"
expect "$ "
interact
在這個腳本里,我們啟動一個ssh進程並連接遠程主機,等待”password:”字符串出現並發送密碼,然後等待”$ “符號表示遠程連接成功,最後輸入”ls”命令並等待”$ “符號再次出現。
四、使用set命令
Set命令用於設置變量的值,方便在腳本中調用。
下面是set命令的使用方式:
set variable value
例如:
#!/usr/bin/expect
set user "foo"
set password "bar"
spawn ssh $user@192.168.1.1
expect "password:"
send "$password\r"
interact
在這個腳本里,我們使用set命令設置變量”user”的值為”foo”,變量”password”的值為”bar”。然後在連接遠程主機時使用變量$user代替用戶名,使用變量$password代替密碼。
五、使用if語句
If語句用於根據條件判斷執行哪些操作。
下面是if語句的使用方式:
if {condition} {
action1
} else {
action2
}
其中,condition是一個條件表達式,action1是條件為真時執行的操作,action2是條件為假時執行的操作。
例如,以下腳本用於判斷遠程主機是否存在某個目錄:
#!/usr/bin/expect
set dir "/home/user"
spawn ssh user@192.168.1.1
expect "password:"
send "mypassword\r"
expect "$ "
send "if [ -d $dir ]; then echo 'yes'; fi\r"
expect "$ "
if {$expect_out(buffer) == "yes"} {
puts "The directory exists."
} else {
puts "The directory does not exist."
}
interact
在這個腳本里,我們連接遠程主機並發送命令查詢目錄是否存在。然後,我們使用if語句判斷目錄是否存在,如果存在則打印”The directory exists.”;如果不存在,則打印”The directory does not exist.”。
六、使用for循環
For循環用於重複執行同一塊代碼多次。
下面是for循環的使用方式:
for {init;condition;step} {
action
}
其中,init是初始變量值,condition是循環條件,step是每次循環後的變化方式,action是每次循環要執行的操作。
例如,以下腳本用於遍歷一個目錄下的文件列表:
#!/usr/bin/expect
set dir "/home/user"
spawn ssh user@192.168.1.1
expect "password:"
send "mypassword\r"
expect "$ "
send "cd $dir\r"
expect "$ "
send "ls\r"
expect "$ "
set filelist $expect_out(buffer)
for {set i 0} {$i < [llength $filelist]} {incr i} {
set file [lindex $filelist $i]
puts $file
}
interact
在這個腳本里,我們連接遠程主機並發送命令切換到指定目錄,然後發送”ls”命令獲取目錄下的文件列表。接着,我們在for循環中使用lindex命令遍歷文件列表,並打印出每個文件的名稱。
七、使用while循環
While循環用於多次執行一個操作,直到滿足某個條件為止。
下面是while循環的使用方式:
while {condition} {
action
}
其中,condition是一個條件表達式,action是每次循環要執行的操作。
例如,以下腳本用於等待遠程主機上的某個程序啟動完成:
#!/usr/bin/expect
set program "/usr/local/bin/myprogram"
spawn ssh user@192.168.1.1
expect "password:"
send "mypassword\r"
expect "$ "
send "nohup $program &\r"
set timeout 30
while {1} {
expect {
"$ " {
break
}
"starting $program" {
sleep 1
}
timeout {
send "\x03"
puts "Timeout waiting for program to start."
exit 1
}
}
}
interact
在這個腳本里,我們連接遠程主機並發送啟動某個程序的命令,並等待程序啟動完成。我們使用while循環和expect命令來檢測程序是否啟動,如果啟動成功則跳出循環,否則一直等待。如果等待時間超過30秒,則打印錯誤信息並退出腳本。
八、使用send命令
Send命令用於模擬鍵盤輸入。
下面是send命令的使用方式:
send string
其中,string是要輸入的字符串。
例如,以下腳本用於向遠程主機發送一個命令:
#!/usr/bin/expect
set command "ls"
spawn ssh user@192.168.1.1
expect "password:"
send "mypassword\r"
expect "$ "
send "$command\r"
expect "$ "
interact
在這個腳本里,我們連接遠程主機並發送命令”ls”,使用send命令模擬鍵盤輸入。
九、使用log_file命令
Log_file命令用於記錄執行過程中的輸出內容。
下面是log_file命令的使用方式:
log_file filename
log_file -noappend filename
其中,filename是日誌文件名。
例如,以下腳本用於連接遠程主機,並將輸出內容保存到日誌文件中:
#!/usr/bin/expect
set log_file "expect.log"
spawn ssh user@192.168.1.1
expect "password:"
send "mypassword\r"
expect "$ "
send "ls\r"
expect "$ "
log_file close
interact
在這個腳本里,我們連接遠程主機並發送”ls”命令,使用log_file命令將輸出保存到日誌文件中。最後使用log_file close命令關閉日誌文件。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/232236.html