你遇到過還有用shell也解決不了的問題嗎?
我遇到過,所以不得不學習彌補shell的弊端的語言Expect;
的確,互動式既是shell的優點,同時也是它的遺憾。
前兩天,因為工作原因需要寫一個自動連接cvs的指令碼,本以為用bash簡簡單單的就搞定了,沒成想可憐的bash死活就是無法自動登入CVS伺服器。
後來想想也應該是,因為shell本身就是一個指令碼,按部就班得做出你所下的各種命令,當你cvs login的時候它是做了,但是現在它做出這個命令之後,已經把控制權轉交給cvs login程式了,再由cvs login提示輸入密碼,判定正確與否。其實你寫的shell只不過之行了一半就跳到別的程式上去執行了。那有沒有能夠實現自動互動的語言呢?答案當然是肯定的。
不知,你是否寫過ftp自動登入的指令碼呢?大體是這樣的:
#!/bin/bash
USER=anonymous
pass="cuitggyy@163.com</P" />
ftp -i -n <<END
open ftp.caldera.com
user $USER $PASS
cd /pub
ls
close
END
看清楚了麼,ftp命令裡有一個“-i”的參數,它的作用是啟動非互動式ftp,而參數“-n”則是關閉自動登入功能。這樣就成了一個作業流的執行方式了,而ftp命令本身能夠避免互動方式的出現,可是我們的CVS伺服器可沒有這麼仁慈的方式,為了安全起見,CVS被設計只能手工輸入密碼的互動式程式,與此相同的還有fsck之類的,因此這就將我們能夠寫一個省事指令碼得方法徹底的打垮。
幸虧我們還有Expect ——這個基於Tcl/Tk的語言,它可以將互動程式以非互動方式運行,彌補了shell的最大弊端。而且Expect的文法也很簡單,寫過shell的一看就明白,下面是我寫的一個簡單的自動登入cvs伺服器得小程式,運行前提當然是已經設定好了正確的CVSROOT:
#!/usr/bin/expect -f
# cvslogin.exp -- auto cvs login
####################
set timeout 10
set passwd [lindex $argv 0]
spawn cvs login
expect "*password:"
send "$passwd\r"
expect eof {exit 0}
timeout {exit 1}
看明白了嗎?簡單吧^_^'' 這樣我們還可以寫出類似的自動登入ssh的小東東,呵呵。
這是我發現的Expect的中文教程:http://www.xfocus.net/articles/200104/169.html
當初我學Expect的時候這個教程還沒出來了,你可以去Expect的官方站搜刮:http://expect.nist.gov/
其實中文教程也是從官方教程翻譯過來的,希望你還是去看官方的,畢竟對E文能有很大提高。
我也是由於工作需要現炒現賣,只不過給有類似問題的兄弟姐妹們提供一種另外解決問題思路,呵呵。