網路農夫 --  Home 網路農夫 --  Home
網路農夫 --  Home
wait.....

3-1 在 C SHELL 下的指令運用

在 UNIX 系統中,指令均以檔案的方式分類存放在檔案系統的數個目錄中。而 C Shell 也其中的一個“指令”。但它的功能卻不止於此,指令們必須透過它所設定的搜尋路徑(path)來執行,變數 path 設定錯誤或指令不在 path 支援的路徑之內,指令是無法執行的。除此外亦可設定別名(aliases)來取代慣用的某個甚至數個特定的、一連串的指令,以免除指令太長或複雜難記之痛 苦。但在這些複雜的功能未介紹之前先來看看光是指令在運用上的變化。

 

3-1-1 單一指令(single command)

 

就 整體而言 UNIX 系統的指令的用法通常都有一個固定的架構。指令使用語法的第一項是指令名稱,然後接著是指令的選項(options)。有時選項後需加上所需的參數。指令 的選項大份均可組合或共同連續使用,功能有時相輔相成;當然也有些選項會有不能混用的情況,但比較少。再來多半便是指令所需的引數,如檔案名稱 (filenames)或目錄(directory)。此部份則有 C Shell 所提供的“wildcard”特殊功能可運用。在 UNIX 系統指令群的功能上則是複雜多變應有盡有強大無比。甚至某些指令的功能發展到可以寫一本專書且欲罷不能(如“sed”“awk”就是),這類指令在指令行 模式下雖然很少用到,但卻常在撰寫 shell 程式發現它們的蹤影,所以說對這些功能強大的工具亦應有所瞭解。在需要運用時才不致於有心無力。

 

在 UNIX 系統的指令中,關於使用者層次的就有二百多個指令,如果將管理階層所使用的指令加進來,那更是有夠驚人。有鑑於此,誠心地希望讀者能養成看 on line manual 的習慣。並且建立自己的指令歸類。因為你對指令的熟悉度將會影響撰寫一個 Shell 程式的成功機率,亦或是 Shell 程式的執行效率。

 

以下由簡而繁舉例說明幾個常用指令:

1. ls
2. ps -axu
3. cp -R ~/akbin akbin.bak
4. find / -type f -name "mem*.c" -print

3-1-2 連續指令(multiple commands)

 

在 C shell 中符號“;”有它特殊作用。當你想在同一行連續下指令時,便可在第一個指令結束後用符號“;”來連接下一個指令。如此可一直連接下去。連續指令的使用格式見下:

command1 ; command2 ; command3;.....

以下我們來看幾個實際的例子

1% cd ~/backup ; mkdir startup ; cp ~/.* startup/.
2% cd ~/akbin ; tar cvf /dev/rst8 *.* >& tar.tmp ; rm -r *.* ; logout

在事件 1 我們改變工作目錄並緊接著建立一個新目錄然後將要備份的檔案拷貝到新的目錄中。事件 2,我們先改變到要備份的工作目錄然後下備份指令並接著在備份完畢後將檔案清除,然後退出系統 logout。以這種方式來連續執行一連串的指令,可讓你一口氣下完一整個流程的工作,在當你有事想離開時,想要的整個流程作業一次完整下完,相當便利。在實際的應用上,常見到他運用在別名的設定上,關於這點我們將在別名中再為你說明。

 

3-1-3 群體指令(commands group)

 

“群體指令”的作用看起來很像“連續指令”,兩者均可將一長串指令加以執行。但就執行的“環境”而言,兩者卻有很大的差異。連續指令在執行時並不先產生一個 subshell 來執行指令。故工作環境會隨著指令的執行而產生變動(如上例連續指令執行完畢後工作目錄便已改變)。但群體指令並不會產生上述的情況。在執行完指令後它會在保留下指令時的工作環境,不會有任何改變。見下例:

% pwd
/home1/akira
% (cd ~/akbin;tar cvf /dev/rst8 *.*)
% pwd
/home1/akira

這是因為群體指令的執行是先自動產生一個 subshell,再將所有指令交由這個 subshell 來執行。當這些指令雖在執行過程中改變了環境變數,但僅是改變 subshell 的環境罷了,一旦指令執行完畢後,subshell 便會自動結束並回到原來的 shell 中,因  subshell 的變數無法影響 parent shell,所以原執行的環境將不會改變。

 

3-1-4 條件式的指令執行(conditional command exection )

 

在 C Shell 中支援兩個特殊符號“||”、“&&”,用來幫助你做簡單的指令執行控制。它是運用一個特殊符號來連接兩個指令,以第一個指令執行狀態的成功與否來決定是不是要繼續執行第二個指令。讓我們來列表說明它的用法:

第一個指令
執行狀態

運用符號

第二個指令
反應狀態

執行成功

| |

不執行

失敗

| |

執行

執行成功

&&

執行

失敗

&&

不執行

特殊符號“||”相當於 else、而特殊符號“&&”則相當於 than。這種相當特殊的指令控制,或許在正常的指令行模式下難得用上,甚至有可能根本用不上。但在 C Shell 程式設計上可是一項相當重要的功能呢。我們來兩個實際應用的例子:

% grep error ecs.sum || lpr ecs.sum

當指令 grep 如果在檔案“ecs.sum”中有找到字串“error”,則不執行列印。如果沒找到任何“error”則執行列印檔案“ecs.sum”。

% ps axu | grep rpc.pcnfsd | grep -v grep > /dev/null && wall pcnfs.run

上面這個例子第一個指令的部份比較複雜,整個指令的功能是找尋系統的處理程序中是否有“rpc.pcnfsd”在執行,如果有則執行第二個指令 wall 向上機的使用者說明,說明的文字內容便是檔案“pcnfs.run”。如果找尋不到,則不執行第二個指令 wall。

 

相信讀者可能會質疑有可能下這樣複雜的指令嗎?老實說在指令行模式下真得相當少。但這項功能在 C Shell 程式設計上則會運用得上,千萬別忽視。切記!切記!

 

版本:Beta-2001-05 -- 網路農夫