2009-08-19 99 views
2

我做了一個Bash腳本,它使用期望腳本來自動執行ssh登錄。該腳本連接到多個服務器並運行一些命令。 bash腳本提示輸入一次登錄憑證。從Bash調用的Expect腳本的退出狀態代碼

我想加入一個功能,其中腳本在第一臺服務器登錄失敗時終止,以避免腳本檢查下一臺服務器導致用戶帳戶被鎖定。帳戶鎖定發生3次連續登錄失敗,腳本嘗試連接的服務器數量超過3個。

這是調用期望腳本的bash腳本中的代碼片段。

countu=0 
for servername in $(cat $linux_host_list) 
do 
./script.expect $LUSERNAME $LPASS $servername Linux >> linux_log_file.txt & < /dev/null 
let countl=countl+1 
done 

這裏是期待腳本(script.expect)片斷

#!/usr/bin/expect -f 
set timeout 30 
set username [lindex $argv 0] 
set SPASS [lindex $argv 1] 
set servername [lindex $argv 2] 
set case [lindex $argv 3] 
set prompt "(%|#|\\$|%\]) $" 
switch $case { 
    Linux { 
     log_user 0 
     spawn ssh -o StrictHostKeyChecking=no [email protected]$servername 
     expect { 
      "assword:" { 
       send "$SPASS\r" 
       expect -re "$prompt" 
      } 
      expect -re "$prompt" 
     } 
     send "sudo su -\r" 
     expect { 
      "assword:" { send "$SPASS\r" } 
     } 
     expect -re "$prompt" 
     log_user 1 
     send "opcagt -status ; opctemplate -l ; cat watch.cf 2> /dev/null\r" 
     expect -re "$prompt" 
     log_user 0 
     send "exit\r" 
     expect -re "$prompt" 
     log_user 1 
    } 

我試圖抓住bash命令輸出($?)假設,如果登錄不正確的失敗bash命令將返回一個非零值期望腳本中的密碼,但沒有解決。 任何建議將不勝感激。

回答

1

你應該認真看看Fabric

+3

老實說,我會猶豫移動到任何超過預期。多年來,Expect一直是實現自動化系統任務自動化的重要工具之一。它做了很多其他這樣的工具無法比擬的東西(例如它幾乎完美地模擬tty /用戶的能力)。這並不是說布料不是很好,因爲我對它一無所知......只是這個Expect有一些很大的鞋子可以填充。 – RHSeeger 2009-08-20 20:13:13

+1

我只是建議這是因爲Fabric只是爲了這樣的任務而製作的。無害! – iElectric 2009-08-25 10:44:45

+0

面料看起來很酷,感謝分享。 – 2010-08-23 22:35:15

0

我倒沒爲腳本和所有的,因此,我不能寫的具體步驟或腳本來證明什麼,我記了 - 敬請原諒

嗯,我讀了慶典提供了一個被稱爲退出狀態的東西

退出狀態是0是真實狀態和1或其他任何虛假

你可以通過執行一個命令,然後鍵入檢查其退出狀態看這個「回聲$?」

我的建議是,當你嘗試ssh到一臺服務器和身份驗證失敗,應當有其他比0

這裏獲得一個if-then-else的循環和檢查狀態爲0東西的退出狀態腳本的執行,任何其他值與相應的錯誤信息

+0

如果您閱讀我的問題,我說我已經嘗試過($?)但是沒有成功。 – Sharjeel 2009-08-20 08:23:51

2

對於錯誤的expect腳本檢查完全退出腳本,有一個在http://systeminetwork.com/article/handle-errors-expect-scripts

一個體面的例子你應該做的是這樣的:

proc do_exit {msg} { 
    puts stderr $msg 
    exit 1 
} 

switch -exact -- $case { 
    Linux { 
     spawn ssh ... 
     expect { 
      -re {assword: $} { 
       send -- "$SPASS\r" 
       exp_continue 
       # remain in this expect block and look for the next matching pattern 
      } 
      "some message about incorrect password" { 
       do_exit "incorrect password" 
      } 
      timeout {do_exit "timed out waiting for prompt"} 
      default {do_exit "something else happened"} 
      -re $prompt 
     } 
     # ... rest of your script 
    } 
} 

我假設您不需要知道「opcagt ...」系列命令的退出狀態(您只想查看watch.cf文件的內容。如果你做護理,你需要得到shell來告訴你:

send -- "opcagt -status 2>&1 || echo "non-zero return from opcagt: $?" 
expect { 
    "non-zero return" { handle error and exit? } 
    -re $prompt 
} 
# ... continue 
0

你在後臺(&)運行預期腳本,所以你不能擁有的第一個結果然後繼續。

您期望的腳本寫入的方式,如果第一次輸入密碼失敗,它將在第二次密碼提示中獲得30秒的超時時間。相反,你可以做一個expect替代方案,看看你是否得到另一個assword提示,並立即退出。

然後將shell腳本更改爲不將期望調用置於後臺,而是使用$?捕獲輸出並對其進行測試。

1

的部分:

expect { 
     "assword:" { 
      send "$SPASS\r" 
      expect -re "$prompt" 
     } 
     expect -re "$prompt" 
    } 

看起來非常可疑給我。特別是,我真的希望這會讓事情變得困惑。一個更習慣寫作的方式是:

expect { 
     "assword:" { 
      send "$SPASS\r" 
      exp_continue 
     } 
     -re "$prompt" 
    }