2015-12-21 73 views
1

爲什麼這個期望的腳本不斷產生ssh命令,從不打印「進入睡眠」或者「離開睡眠」,並且從不睡覺?爲什麼不這樣期待句柄超時或者eof

我的意圖是嘗試ssh'ing,如果它看到「password:」以退出while循環(更多代碼在這裏看不到會包含交互)。如果3秒鐘過去,或ssh在此之前死亡,它會應該放3秒睡,再放,然後再試ssh。

主機名「doesntexist」用於強制失敗,例如名稱或服務未知。

#!/usr/bin/expect -f 

set readyForPassword 0 
while { $readyForPassword == 0 } { 
    spawn ssh [email protected] 
    expect -timeout 3 { 
     "password: " { 
     set readyForPassword 1 
     } timeout { 
     puts "going to sleep" 
     sleep 3 
     puts "out of sleep" 
     } eof { 
     puts "going to sleep" 
     sleep 3 
     puts "out of sleep" 
     } 
    } 
} 
+0

呵呵。如果我刪除了{在期望行結束時(及其底部附近的大括號)並使期望行爲'expect -timeout 3「密碼:」{「然後它按預期工作。探索Expect說,你可以按照我原來的方式來支撐它,至少在p76我想。期望改變嗎?我誤解別的東西了嗎? – user1902689

回答

3

當使用-timeout標誌,應當先於Expect的圖案,不執行的操作。

通過調試,我們可以發現,該模式所採取Expect與您現有的代碼,

expect: does "" (spawn_id exp6) match glob pattern "\n  "password: " {\n   set readyForPassword 1\n  } timeout {\n   puts "going to sleep"\n   sleep 3\n   puts "out of sleep"\n  } eof {\n   puts "going to sleep"\n   sleep 3\n   puts "out of sleep"\n  }\n "? no 

Exploring Expect書的第76頁,我們可以看到下面的語句,

初始打開大括號會導致Tcl繼續掃描其他 行以完成該命令。一旦匹配的括號中發現,外括號之間的模式和操作的所有 傳遞給 期待作爲參數

出了什麼問題呢?

-timeout不是一個動作,而只是一個標誌。預期假設如下的模式

"password: " { 
     set readyForPassword 1 
     } timeout { 
     puts "going to sleep" 
     sleep 3 
     puts "out of sleep" 
     } eof { 
     puts "going to sleep" 
     sleep 3 
     puts "out of sleep" 
     } 

記住,Expect不強制行動,只有模式,即好像我們只喜歡圖案被賦予它會採取行動,但沒有應採取的行動。

簡單地說,你的代碼是等同

expect "Hello"; # Either 'timeout' or pattern can be matched. But, no action at all 

您的代碼應該被重新安排爲,

#!/usr/bin/expect -d 
set readyForPassword 0 
while { $readyForPassword == 0 } { 
    spawn ssh [email protected] 
    expect { 
     -timeout 3 "password: " {set readyForPassword 1} 
     timeout { 
       puts "going to sleep in timeout" 
       sleep 3 
       puts "out of sleep in timeout" 
     } eof { 
       puts "going to sleep in eof" 
       sleep 3 
       puts "out of sleep in eof" 
     } 
    } 
}