farmer-logo.gif (14959 bytes) cshell-logo.gif (19625 bytes)
ch-3.gif (10141 bytes)
main-b.gif (271 bytes)
 

 

3-8-9 rehash、unhashhashstat 指令

這三個內建指令 rehash、unhash、hashstat 在功能上息息相關於一項 C shell 對尋找指令檔案的加速做法。這項加速法叫“internal hash table”。這三個內建指令便是用來做有關於“internal hash table”的資料更新、不使用的設定及顯示“internal hash table”的資料狀態。

C Shell 運用了 internal hash table 的方式,來加速在 path 變數的目錄群中搜尋指令執行的速度。也就是因為使用了 internal hash table 的來記憶指令的位置,以至於產生了一個使用上必須注意的小小限制。這個限制便是當你新加入一個可執行的程式到 path 變數的目錄中,如果你不將 internal hash table 更新的話,你只能在該程式所在的目錄下執行。當你改變工作目錄到別的目錄中要執行那個新程式,雖然它確實是在 path 變數的搜尋目錄中,在理論上應該會找到它,但其實不是這回事。你執行時將會驚訝地發現“: Command not found.”的錯誤訊息。千萬別以為電腦又出毛病了,這是正常現像。你在這個時候只要用指令 rehash 將 internal hash table 更新便可以搜尋到該新增的程式了。讓我們來設定一個比較單純的環境來實際試一試:

2 % set path = ( /usr/ucb /bin /usr/bin ~/bin)
3 % cd ~/bin
4 % echo ps > test ; chmod u+x test
5 % cd
6 % test
test: Command not found.
7 % rehash
8 % test
PID TT STAT TIME COMMAND
4049 p0 S 0:00 -csh (csh)
4075 p0 S 0:00 /bin/sh /home1/akira/bin/test
4076 p0 R 0:00 ps

從上例中,我們清楚地看到指令 6 的執行結果是“test: Command not found.”,而經過指令 7 用 rehash 內建指令將 internal hash table 更新後,新增的執行檔 test 便能被搜尋到,並由執行訊息中我們清楚地看到 test 檔所在的目錄。

最後為你介紹的是指令 hashstat,它會顯示 internal hash table 的三項統計性資料。如下例:

20 % hashstat
15 hits, 5 misses, 75%

第一部份是是使用 internal hash table 的有效數值。第二部份是則是使用失效記錄。第三部份是成功的百分比。關於第二部份為何會產生失效的情況,我們將為你稍加說明。

當我們鍵入指令後, C shell 經判斷不是內建指令或別名後,便使用 internal hash table 搜尋該指令位置,如果發現沒有該指令,便輸出訊息“xx: Command not found.”。如果說你的 path 變數中沒有“.”(dot)這個符號的話,便不屬於“失效”。因為失效的意義是指 C shell 有使用到 exec() 這個 system call 為你執行該指令卻產生錯誤時,才算是“失效”。譬如執行時產生 Permission denied 的情況,便是屬於失效的情況。或許你會感到奇怪,為何我們在前面所提到的 xx: Command not found.”的情況中,為何要排除“.”(dot)這個符號呢?因為它在執行上比較特殊。當 C shell 使用 internal hash table 在搜尋指令位置時,碰到“.”(dot)這個符號便會以 exec() 這個 system call 來執行“./command”。如果執行失敗,將馬上為你記上一筆。如果你所設定的 path 變數有加上符號“.”(dot),而且還是放在最前面,在此建議你最好考慮將它移到 path 變數的最後面。因為在你每次使用到系統指令時都會發生一次不必要的錯誤,在無形中將會降低系統的效率。當然最好是放棄在 path 變數使用符號“.”,需要時在以“./command”的方式來執行也可以。

由於 C shell 對於“internal hash table”的使用系統所定義的初始值是使用的狀態,所以當你不想要有上述這樣擾人的情況,要放棄使用 internal hash table 這項功能也可以。 C shell 提供你內建指令 unhash 來解除這個問題。但就整體的使用效率而言,最好還是別輕易放棄使用 internal hash table。因為當你放棄使用 internal hash table,搜尋指令執行的方式將會改便成最原始的狀態。就是要執行一個指令便逐一的到 path 變數的目錄群 中去嘗試著執行。就如下面的例子:

19 % hashstat
10 hits, 0 misses, 100%
20 % unhash
21 % grep akira /etc/passwd
akira:lv8u/EYmXK5kU:101:100:SYMBAD USER:/home1/akira:/bin/csh
22 % hashstat
11 hits, 1 misses, 91%
23 % echo $path
/usr/ucb /bin /usr/bin /home1/akira/bin
24 % rehash

在放棄使用 internal hash table 前,指令 hashstat 告訴我們“失效”為“0”。然後我們鍵入 unhash,放棄使用 internal hash table。接著我們操作一般的系統指令如 grep,在顯示使用情況,卻得到失效”為“1”,這是為什麼呢?因為不使用 hash table後,要執行指令 grep 的動作變成到 path 變數的目錄群中去“嘗試執行”,第一先以“/usr/ucb/grep”執行,發現沒有該指令,所以 exec() 的動作失敗。再來以“/bin/grep”執行,該指令存在, C shell 便為你執行該指令。這便是放棄使用 internal hash table 的指令執行方式。相當地“原始”是吧!請考慮清楚再使用。如果要恢復使用 internal hash table,鍵入 rehash 便可。


mail.gif (2925 bytes)

b-line.gif (2092 bytes)