一、概述
在Linux環境,有多種實現自己主動化的腳本語言。如Shell、Python、Perl、Tcl等。
Shell語言因與Shell外殼結合緊密,是最常見的實現自己主動化的腳本語言。
同一時候,在Linux環境中存在大量功能單一的小工具——通常它們在指定輸入后,馬上就可獲得輸出,比如echo、cat等字符串/文本打印工具。又或者是如sed、awk等最經常使用的字符串編輯工具。通過編寫Shell腳本,我們能夠重復利用這些小工具來實現一些自己主動化的批處理。
在少數情況下,我們也須要用到一些交互式的工具,比如passwd、fdisk等——這意味着在自己主動化運行的過程中,我們必須停頓下來,滿足工具本身的交互式流程。
本文將介紹兩種在使用交互式命令時規避交互來實現自己主動化的方式。
二、用分界符控制交互式命令
Shell中的 ‘<<’符號表示一種特殊的重定向,用於向某一個命令傳遞多行輸入。當腳本中出現此符號時。Shell將首先會把緊跟着‘<<’的一個字符串,視為一種特殊的分界符;然后。用戶能夠輸入一連串的數據;最后,用戶單獨起一行,用還有一個同樣的分界符結尾。在兩個分界符之間的內容,都被視為命令的輸入參數。
我們在實際的軟件開發項目中看到最多的就是用cat向一個文件輸入一段文本。比如以下的example1.sh腳本中的內容:
cat > example1.sql <<EOFSQL
declare @num int, @sql nvarchar(1000)
set @sql='select @a=count(*) from tableName '
exec sp_executesql @sql,N'@a int output',@num output
select @num
<<EOFSQL
該腳本的運行結果是生成一個example1.sql文件。內容為兩個分界符EOFSQL之間所看到的的內容。
用cat命令向一個文本輸入字符串,本身不是交互式的。當使用交互式命令時,分界符便能夠控制命令的輸入參數,滿足不同的控制流的要求。
三、用expect命令控制多個命令
在運行另外一些操作(如ssh登錄)時。我們無法用分界符的方法來輸入多個命令,由於ssh的輸入來源是終端(分界符的輸入。應理解為通常意義上的字符串)。這時,我們能夠考慮用expect命令。
expect命令是Linux中專門以非交互式方法處理交互式命令的工具。相比分界符來說,它更為強大。且能實現分界符能實現的一切功能。
expect命令的工作原理是在shell中另啟一個新進程,而且在此進程中模擬了終端,對輸入/輸出進行全面監控。而要使用expect命令。則必須須要編寫獨立的腳本。
expect有相當多的參數和語法。以下我們僅介紹一些基礎部分,供大家參考。
1.[#! /usr/bin/expect]
expect腳本的第一行總是用這個語法。這相似於shell腳本的#! /bin/sh。這句話的含義也是定義腳本的解釋器。
值得注意的是,依據操作系統的不同,expect命令的位置也可能是在 /usr/local/bin/expect。使用前。用戶應確認工具是否存在(確認方法是在root用戶下運行“which expect”命令)。
2.[set timeout 30]
設置響應的超時時間,計時單位是秒。設置timeout -1表示永不超時。
3.[spawn ssh -l username ip]
spawn是進入expect環境后才干夠運行的expect內部命令。
它基本的功能是給ssh運行進程加個殼,用來傳遞交互指令。
4.[expect "xxxxx:"]
這里的expect也是一個內部命令。
這個命令的意思是推斷上次輸出結果里是否包括“xxxxx:”的特定字符串。假設有則馬上返回。
expect還有些擴展的使用方法,最常見的例如以下所看到的:
expect {
“xxx1” {command1;exp_continue}
“xxx2” {command 2}
}
以上代碼的含義如同C語言的switch語句,不同的條件相似不同的case子句。
而當中的exp_continue就如同不加break語句,程序將繼續運行后面的語句。
5.[send "ispass\r"]
這是運行交互動作,即模擬終端進行輸入。值得注意的是,命令字符串結尾別忘記加上“\r”。
6.[expect eof]
退出expect解釋器 。
以下是一個使用expect命令的實例:
#! /usr/bin/expect -f
set timeout -1
spawn ssh -l zhou 10.10.10.10
expect {
"yes/no" { send "yes\r";exp_continue}
"*assword:" {send "zhou"}
}
expect "*>" {send "echo’HelloWorld!’\r"}
expect "*>" {send"exit\r"}
expect eof
演示樣例中。我們通過ssh以用戶zhou登錄了10.10.10.10,然后向ssh輸入該用戶的password。
登錄成功之后,我們打印“Hello World。”。之后退出ssh,結束expect命令的運行。
expect命令的更具體使用方法請參考man手冊。
四、總結
本文簡單地介紹了在Linux下,兩種使用交互式命令時規避交互來實現自己主動化的方式。供相關的開發者參考。
-----------------
本人微信公眾號:zhouzxi。請掃描以下二維碼:

