2015-03-13 32 views
0

我有一個tcl(expect)腳本來登錄到設備和傳輸文件。不幸的是,這些文件很大,在傳輸期間ssh連接結束(文件仍然被傳輸)。所以我基本上必須再次登錄才能在設備上執行更多操作。由於整個登錄過程很長,我把它放在一個proc中。問題是proc登錄到設備中,但登錄後,腳本將命令發送到終端,因爲某些原因,命令不再到達設備。我不知道爲什麼我在proc中登錄的會話沒有傳遞給腳本的其餘部分。使用tcl proc登錄到設備

proc login {} { 
    #login code - it works because I took it from the main script (which works). 
    # variables are all declared as global, no errors are thrown. Login is successful 
} 

login 

send "show\r" ;# this command is not sent to the device, 
#instead it prints to the terminal. When in the main script, 
#these commands would not be printed to the terminal window. 

是否有一個命令我想失望,可能會返回登錄會話到腳本的其餘部分?類似於interact命令的內容,但涉及腳本的其餘部分。

回答

1

的第一線,使在其調用者的範圍評估代碼的程序,你需要使用它裏面的uplevel命令。這可以讓你做什麼本質上是一個宏很容易:

proc login {} { 
    uplevel { 
     # Put your code in here, which might look like this 
     spawn ssh [email protected] ... 
     expect Password: 
     send $thePassword\r 
     expect "bash$" 
    } 
} 

然後,當你使用login它將工作正是就像你在程序中uplevel中的命令,好像他們一直類型代替撥打login

這通常不是一個特別推薦的方法,因爲它很容易使代碼不靈活並傾向於意外中斷,但在您的情況下,這是一種非常簡單的方法,因爲您可以輕鬆保證只調用login在整個計劃結構中合理的地方。 (uplevel命令更常用於使用參數傳入的腳本 - 它就像您正在傳遞的塊 - 但這不是您需要的。)

+0

是的!這工作,非常感謝! – user2883071 2015-03-16 14:33:19

2

這是一個棘手的問題。期望手冊頁這樣說:

期望採取一個相當寬鬆的範圍界定。特別是,通過指定的 命令讀取到Expect程序的變量將首先從本地範圍中查找,如果未找到,則在全局範圍內查找。例如,這避免了在您使用期望編寫的每個程序 中放置「全局超時」的需要。另一方面,寫入的變量總是在本地範圍內(除非已發佈 「全局」命令)。 這個問題導致的最常見問題是在 過程中執行spawn時。在程序之外,spawn_id不再存在,所以產生的過程不再僅僅因爲作用域而可以訪問 。 添加一個global spawn_id到這樣的程序。

所以,加global spawn_id作爲login PROC

+0

不幸的是,當我這樣做時,它會拋出一個錯誤,指出'cant閱讀expect_out(緩衝區):沒有這樣的變量。在後面的代碼中,我依賴於show命令的輸出。 – user2883071 2015-03-13 18:14:20

+1

因此,使用'global spawn_id expect_out' – 2015-03-13 18:33:48

+0

它仍然不會將命令發送到設備。這些命令仍然顯示在終端上。現在我可以繼續將登錄代碼複製到需要的地方。 – user2883071 2015-03-13 18:47:18