在 python 中有一個 telnetlib,它的作用就是建立一個通到主機的 telnet連線實體, 然後向主機傳送命令 (就像用鍵盤輸入一樣 )並從該連線接收資料。利用它, 我們可以把示範 1的所有內容從 "人 -機 '交流變成'機 -機 '交流,這樣也可以做到處理 pop3 郵箱的工作。不過既然我們已經試過了 pop3,這一次可以試用真的 telnet 埠 23 做些好玩的東西。
以下是程式碼片段: 1 # telnetdo.py 2 #!/usr/bin/env python 3 4 def telnetdo(HOST=None, USER=None, PASS=None, COMMAND=None): #定義一個函數, 這將要用它會很容易 5 import telnetlib, sys 6 7 if not HOST: #如果沒有給出所要的資料,則要求使用者輸入 8 try: 9 HOST = sys.argv[1] #記得吧, 序列是從 0開始數的,而sys.argv[0]會是你程式的名字 10 USER = sys.argv[2] 11 PASS = sys.argv[3] 12 COMMAND = sys.argv[4] 13 except: 14 print "Usage: telnetdo.py host user pass 'command'" 15 return 16 17 msg = ['Debug mesages:\n'] #這個用來存起所有從主機傳回的訊息, 作除錯時很有用 18 19 tn = telnetlib.Telnet() #準備一個 telnet 連線的實體 20 try: 21 tn.open(HOST) #串連端綁定到主機 HOST 去 22 except: 23 print "Cannot open host" 24 return 25 26 msg.append(tn.expect(['login:'],5)) #等待主機傳回含有 'login:'字元的訊息,等候時限為 5秒 27 tn.write(USER+'\n') #向主機送出字串 USER + '\n',如 USER 是 28 # 'pcheung' 則等於 'pcheung\n' 29 if PASS: #就像是在鍵盤打入一樣。 30 msg.append(tn.expect(['Password:'],5)) #如果有 password 要打的話就送出密碼字串, 31 tn.write(PASS+'\n') #但首先要等主機傳回含有 'Password:'字樣的訊息 32 33 msg.append(tn.expect([USER],5)) #因為通常登入後主機會顯示出登入者名稱,我們在主機回應中找這 34 #樣的字元,如有的話則代表登入成功了 35 tn.write(COMMAND+'\n') #向主機發出指令 36 msg.append(tn.expect(['%'],5)) #等 5秒,如果程式完成了一般我們會收到 37 # shell prompt 吧,假設為 '%' 38 tn.close() #關閉連線 39 del tn 40 return msg[len(msg)-1][2] #把收到的訊息通通傳回去。 41 #(注意 msg 中第 2個元素才是真的訊息, 42 #其他是附加資訊。 43 44 if __name__ == '__main__' #這是 python 常用的技巧:如果 telnetdo.py 程式 45 #是從 command prompt 46 #引發的話則 __name__ 的內容為 __main__,相反 47 #如果是從別的程式用 import telnetdo 的話則 48 # __name__ 會變成 'telnetdo' 49 print telnetdo() #這樣寫的好處是從此 telnetdo 會成為你的擴充 50 #模組,你可以在別的程式中 51 #用telnetdo.telnetdo(HOST,USER,PASS,COMMAND)來調用它!
這個程式用法如下:
以下是程式碼片段:> chmod +x telnetdo.py > telnetdo.py 'somehost' 'glace' 'xxxxxx' 'ls -lF' (0, <SRE_Match object at 200f75a8>, '\015\012\015\012Linux (somehost)\015\012\015\015\012\015login: ') (0, <SRE_Match object at 20124848>, 'Password:') (0, <SRE_Match object at 20103e08>, '\015\012Yup Release 2.6 somehost\015\012Last login: Wed Mar 6 18:21:01 GMT 2002 by UNKNOWN@xxx.xxx.xxx.xxxyou have mail\015\012somehost:glace%') total 320 -rw-r--r-- 1 glace user 139788 Feb 8 17:54 PQR2.1.txt drwxr-xr-x 3 glace user 4096 Feb 10 16:45 mytts/ drwxr-xr-x 3 glace user 4096 Jan 29 19:03 sample/ drwxr-xr-x 2 glace user 4096 Jan 6 16:38 tex/ drwxr-xr-x 2 glace user 4096 Sep 5 2001 tmp/ drwxr-xr-x 2 glace user 29 Feb 23 2001 tools/ drwxr-xr-x 2 glace user 26 Feb 6 18:43 trash/ somehost:glace% 可以看到執行的結果和一些附加的資訊。這就是遠端執行程式了。就算沒有 rsh,照用可也。 哈,很方便吧。不過你應該留意到了程式執行時只等候了 5秒,就是說如果你要向主機發出像 'find . -name xxx -print' 這樣的命令應該等不到執行完這個 telnet session 就會被關閉了。不過仔細想一下,這要緊嗎?我們現在所能做到的和真正人手 telnet 的差別並不大,想一想你會怎樣解決長時間執行的問題?沒錯,就是 'nohup'和背景作業了。 就是說只要把程式呼叫改成: telnetdo.py 'apocal' 'pcheung' 'xxxxxx' 'nohup myprogram_or_script&' 就行了。如此一來,就算對方主機的 shell prompt 是 '>'或是 '>>>'都沒有關係了。
(注意安全性並非是這類範常式式的著重點, 因此並不建議在實際工作中用它.)