1. 程式人生 > >每次進步一點點——linux expect 使用

每次進步一點點——linux expect 使用

1. 介紹

expect是建立在tcl(參見:Tcl/Tk快速入門 )基礎上的一個工具,它可以讓一些需要互動的任務自動化地完成。相當於模擬了使用者和命令列的互動操作。
一個具體的場景:遠端登陸伺服器,並執行命令
登入時輸入密碼需要互動,bash指令碼無法完成,可以使用expect來完成。

2. 安裝

下面介紹兩種安裝方式

yum 安裝

yum install -y expect

原始碼編譯安裝

expect 依賴於 tcl, 所以需要首先安裝 tcl。可以使用rpm檢查是否已經安裝tcl:

rpm -qa | grep tcl

如果已安裝,則會打印出tcl軟體資訊

3. 原理與工作機制

首先使用 spawn 開啟一個會話,然後使用 expect-send 對來執行互動式操作。
spawn 後面跟上一個命令操作,表示開啟一個會話。expect 等待輸出特定的字串(通常是提示符),然後使用send 傳送互動字串。比如:

spawn ssh [email protected] # 遠端登入

expect "*assword" # 提示為:"[email protected]'s password:", 等待使用者輸入密碼
send "${password}\r" # 這時使用send模擬使用者輸入密碼的字串,完成登入驗證

4. 基本語法介紹

指令碼直譯器

指令碼中首先引入檔案,表明使用的是哪一個shell

#!/usr/bin/expect

set

設定會話超時時間為30s, 若不限制超時時間則應設定為-1

set timeout 30

set 還可以設定變數

# 使用變數語句:$param 或者 ${param}({}用來避免param和後面的字串拼接起來導致錯誤)
set param "param_str"
set param 1

spawn

spawn 後面跟一個命令,開啟一個會話

spawn ${cmd} # for example : spawn su root

expect - send

expect 接收命令執行後的輸出,然後和期望字串匹配,若對應這執行相應的send來發送互動資訊。

expect "$case1" {send "$respond1\r"} # 這一行等同於下面兩行

expect "$case1"
send "$response1\r"

expect 可以有多個分支,就像switch語句一樣。

expect 
{
    "$case1" {send "$response1\r"}
    "$case2" {send "$response2\r"}
    "$case3" {send "$response3\r"}
}

結束符

expect eof :等待執行結束,若沒有這一句,可能導致命令還沒執行,指令碼就結束了
interact : 執行完成後保持互動狀態, 這時可以手動輸入資訊
:expect eof 與 interact 二選一即可

接收引數

引數存在argv中,使用第一個引數如下:

set param0 [lindex $argv 0]

$argc表示引數個數,判斷語句如下:

if {$argc < 1} {
    #do something
    send_user "usage: $argv0 <param1> <param2> ... "
    exit
}

注:$argv0 是指令碼名,但[lindex $argv 0]是第一個引數 param1, [lindex $argv 1]是第二個引數 param2, 以此類推
send_user 用來顯示資訊到父程序(一般為使用者的shell)的標準輸出。

5. 例項

實現遠端登入伺服器,並切換到root使用者下執行關閉防火牆的命令,然後退出

#!/usr/bin/expect

if {$argc < 4} {
    #do something
    send_user "usage: $argv0 <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>"
    exit
}

set timeout -1
set remote_user [lindex $argv 0] # 遠端伺服器使用者名稱
set remote_host [lindex $argv 1] # 遠端伺服器域名
set remote_pwd [lindex $argv 2] # 遠端伺服器密碼
set remote_root_pwd [lindex $argv 3] # 遠端伺服器根使用者密碼

# 遠端登入
spawn ssh ${remote_user}@${remote_host}
expect "*assword:" {send "${remote_pwd}\r"}
expect "Last login:"

# 切換到 root
send "su\r"
expect "*assword:" {send "${remote_root_pwd}\r"}

# 執行關閉防火牆命令
send "service iptables stop\r"
send "exit\r"
send "exit\r"
expect eof

將程式碼儲存到 remot_root_command.exp 中,許可權改為755,然後執行下面這條命令即可:

./remote_root_command.exp <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>

相關推薦

每次進步點點——linux expect 使用

1. 介紹 expect是建立在tcl(參見:Tcl/Tk快速入門 )基礎上的一個工具,它可以讓一些需要互動的任務自動化地完成。相當於模擬了使用者和命令列的互動操作。 一個具體的場景:遠端登陸伺服器,並執行命令 登入時輸入密碼需要互動,bash指令碼無法完

每天進步點點——Linux中的檔案描述符與開啟檔案之間的關係

    在Linux系統中一切皆可以看成是檔案,檔案又可分為:普通檔案、目錄檔案、連結檔案和裝置檔案。檔案描述符(file descriptor)是核心為了高效管理已被開啟的檔案所建立的索引,其是一個非負整數(通常是小整數),用於指代被開啟的檔案,所有執行I/O操作的系統呼叫都通過檔案描述符。程式剛剛啟動的

每次進步點點——spark中cache和persist的區別

昨天面試被問到了cache和persist區別,當時只記得是其中一個呼叫了另一個,但沒有回答出二者的不同,所以回來後重新看了原始碼,算是弄清楚它們的區別了。 cache和persist都是用於將一個RDD進行快取的,這樣在之後使用的過程中就不需要重新計算了,可

每天進步點點——Linux程式設計中的檔案鎖之flock

無論程式以什麼模式打開了檔案(讀、寫或者讀寫),該檔案上都可以放置一把共享鎖或互斥鎖。在實際操作過程中,引數operation可以指定對應的值將共享鎖轉換成互斥鎖(反之亦然)。將一個共享鎖轉換成互斥鎖,如果另一個程序要獲取該檔案的共享鎖則會阻塞,除非operation引數指定了LOCK_NB標記,即:(LOC

每天進步點點——Linux中的執行緒區域性儲存(二)

凡是帶有__thread的變數,每個執行緒都擁有該變數的一份拷貝,且互不干擾。執行緒區域性儲存中的變數將一直存在,直至執行緒終止,當執行緒終止時會自動釋放這一儲存。__thread並不是所有資料型別都可以使用的,因為其只支援POD(Plain old data structure)[1]型別,不支援clas

PHP每天進步點點 常用linux命令

sel grant ls -lh 進程id add word ls -l linux命令 一個 日常用的,歡迎拍磚 1.創建目錄:mkdir xxx2.查看nginx安裝目錄:ps -ef|grep nginx3.給文件夾一個權限:chmod 777 xxx4.查看lin

每天進步點點——論fork()函式與Linux中的多執行緒程式設計

1. 雖然只將發起fork()呼叫的執行緒複製到子程序中,但全域性變數的狀態以及所有的pthreads物件(如互斥量、條件變數等)都會在子程序中得以保留,這就造成一個危險的局面。例如:一個執行緒在fork()被呼叫前鎖定了某個互斥量,且對某個全域性變數的更新也做到了一半,此時fork()被呼叫,所有資料及狀態

每天進步點點——Ganglia的Python擴展模塊開發

mar 命令 啟動 time_t 重新 source https code eight 轉載請說明出處:http://blog.csdn.net/cywosp/article/details/39701245 註:本文涉及到的代碼都在centos

每天進步點點-Java Serializable(對象序列化)的理解和總結

height puts 信息 new 網絡 停止 之間 internet clas 往硬盤文件裏寫數據 序列化:序列化是將對象轉換為容易傳輸的格式的過程。例如,可以序列化一個對象,然後使用 HTTP 通過 Internet 在客戶端和服務器之間傳輸該對象。在另一端,反序列

程序員,你要每天進步點點-轉載

事情 說了 相愛 調優 集中 nbsp 中間數據 丟了 試驗 第1個一點點:專註眼下 見過太多心猿意馬的程序員,我不得不把「專註眼下」作為天字第一條。他們往往有各式各樣的小夢想,比如做個小茶農、做個小鵝販、做產品、做銷售、做投資,卻被程序員的高薪或是沒有轉行的魄力「耽誤」了

Python 3爬蟲網易雲(五)——每天進步點點(正則表達式下篇之HTML標簽)

tdd htm python swf sofm pts 正則表達 eal href 51忠酶9euka杖淪28炊http://jz.docin.com/ngaxf40277 嵌擲Ic白冉qgw抑亢84http://jz.docin.com/fejci232 gw2d4永

每天進步點點001

程序 存儲 進步 並且 世紀 src png 一點 每天 進步一點點之:2017-09-20 翻譯:很難確切的說現代計算機是在什麽時候發明的。從20世紀30年代到20世紀40年代,許多類似計算機的機器被發明出來。但是這些機器並不具備當代計算機的所有特性。這些特性是機器是電

每天進步點點006

一點 alt self. logs 每天 eat 計算 二進制 instead 翻譯:EDVAC完成之前,許多其他的機器被研制,吸收了Eckert、Mauchly和Neuman設計的要素。其中一部是電動的延遲存儲自動計算機,或簡稱EDSAC,在英國的劍橋大學研制,在194

每天進步點點016

con err sin logs 其中 使用 into src 負責 翻譯:Remintong Rand,現在叫Sperr-Rand Corporation,它制造了許多第二代UNIVAC計算機。然而IBM仍然占據市場,其中最出名的第二代計算機之一是IBM 1401,它是

每天進步點點020

編寫 這才 bsp then .com image cnblogs ole .cn 翻譯:雖然集成電路在1958年被發明,但是第一臺計算機直到1964年才廣泛使用。在那一年,IBM引進了一臺叫System/360大型計算機系列。這一系列計算機成為了使用最廣泛的第三代機器。

每天進步點點029

而不是 但是 logs 現實 es2017 ble more 自己 cnblogs 翻譯:我們可能已經定義了最近的一代計算機並開啟了無代計算機的新時代。雖然計算機制造商稱呼第五代和第六代計算機,但是這種稱呼更多的是一種市場影響而不是現實表現。 備註:meditate(沈思

每天進步點點030

under es2017 nbsp inno 每天 most working spring ati 翻譯:無代計算機觀念提倡者聲明,雖然技術的革新正快速的一個接一個的到來,但沒有一種革新是,或將是足夠重要作為另一代計算機的特征。 備註:advocate(提倡者、擁護者、主

PHP 每天進步點點 按照固定字段排序

每天 sort turn 進步 public key list ret return public function sortbykey($key,$list,$sort) { $flag = array();

PHP每天進步點點 代碼規範之PSR-2

abs bstr oob class turn 表示 interface 名稱 限制 1.概覽 代碼必須遵循PSR-1基本代碼規範。 代碼必須使用四個空格符進行縮進,而不是一個tab鍵。 每行應該保持在80個字符以內,軟限制必須是120個字符,但一定不能有硬性限制。 每個

【每天進步點點--Python】 元組 tuple 詳解

Python 元組 Python的元組與列表類似,不同之處在於元組的元素不能修改。 元組使用小括號,列表使用方括號。 元組建立很簡單,只需要在括號中新增元素,並使用逗號隔開即可 例項: tup1 = ('physics', 'chemistry', 1997, 2000) tup2 =