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

3-6 別名(aliases)的設定與運用

設定語法 alias name 'command'
解除設定語法 unalias name
顯示設定語法 alias (顯示所有別名設定)
alias name (顯示name的別名設定)

別名(aliases)是 C Shell 的內建指令。主要的功能是設定一個“小名”來取代常用的或複雜的指令組合。在應用上可說是最多樣、方便的好功能(此 aliases 功能在 Bourne Shell 中不支援)。在下例中便是別名的設定、顯示、使用情況:

2 % alias ls 'ls -aF'
3 % alias ls
ls -aF
4 % ls
./ ../ .cshrc* a b file login logout

當我們在使用常用的指令時,總不免會固定地使用指令的某一些選項。所以有人便使用設定 aliases 的方式來代替之。這是 aliases 最常見的應用。如上例我們設定一個叫“ls”的 aliases,它所代表的是指令“ls -aF”。在設定完之後我們所執行的 ls 指令其實已經不是原來系統的指令ls,而是“ls -aF”。這全與 C Shell 對指令執行的解譯流程問題有關。因為 C Shell 在替使用者解譯鍵入的指令時,如果是屬於 C Shell 的內建指令,則會直接執行。如果指令是以符號“/”為開頭,則將會被認定為是路徑名稱,並會到該路徑下去搜尋該指令並加以執行。如果開頭沒有“/”符號,則會有兩種情況,依變數 path 裡所設定的目錄逐序加以搜尋及執行,這是一般的情況。但如果該指令名稱在內建指令 alias 所建立的資料內被發現,則 C Shell 會先將該指令名稱轉換成內建指令 alias 所建立的對映資料,再依此資料內容到變數 path 裡所設定的目錄群中去搜尋與執行。這便是設定 aliases 後會取代原指令執行的原因。

這種 aliases 名稱與系統指令名稱相同的設定,雖然帶給我們在指令使用上的方便,但也會造成一些在使用指令上的負面影響,使用者不可不小心謹慎。譬如在“ls”已被設定為“ls -aF”的情況下,我們鍵入“ls -l”,則真正執行的其實是“ls -aF -l”。而不是原指令 ls 的“ls -l”。這一點請讀者務必認識清楚。

如果你想要將“ls”的 aliases 設定消除,可用指令 unalias 在指令行模式下解除“ls”的設定,如下所示:

5 % unalias ls

如果說你在不想解除 ls 的 aliases 設定情況之下,想要運用原指令 ls。有兩種方式,第一:指令要以絕對路徑的方式來執行,以指令 ls 為例,須鍵入 /bin/ls 來執行。但這種方法老實說是比較笨的人用的。第二種方法是運用 C Shell 為我們所提供的特殊符號“\”擋去 alias 指令的設定,達到你要使用原指令的需求。如下所示:

6 % \ls
a b file login logout

如此你便可在指令的使用上得到更大的彈性,做更有效率的運用。

aliases 通常均設定在 C Shell 的啟始檔案“.cshrc”中;也可簽入後在設定,不夠設定值會隨著 logout 或 shell 的終止而消失。最好的方式還是設定在“.cshrc”檔案中,對使用上比較方便。

簡單的 aliases 設定如“alias ls ls -asF”或“alias rm rm -i”等可不用符號來括住指令,但如果是指令組合中有運用到連續指令的符號“;”時,則一定得用符號來將指令組合括住,否則設定將出現問題。所以在設定 aliases 最好養成用符號將指令組合括住的好習慣。如下例,第一個 aliases 設定便是錯誤;而第二個有括住指令組合的,才是正確的。

% alias ww who ; date
alias ww who
date
Mon Sep 12 03:06:32 CST 1994
% ww
who
akira ttyp0 Sep 12 02:34 (akirahost)
% alias ww 'who ; date'
alias ww who ; date
% ww
who
akira ttyp0 Sep 12 02:34 (akirahost)
date
Mon Sep 12 03:09:28 CST 1994

3-6-1 別名設定中運用事件的引數

 

在別名的設定是允許代入變數或使用引數的。先來看看一般使用者常用來查看系統是否執行某個 process 的指令組合:

% ps axu | grep pattern (pattern代表process的名稱)

如果像以上指令設定為下:

% alias psg 'ps axu | grep'

讓我們來實際運用這個 psg 來尋找 cron 這個 process 看看:

/home1/akira> set echo
/home1/akira> alias psg 'ps axu | grep'
alias psg ps axu | grep
/home1/akira> psg cron
ps axu
grep cron
root 136 0.0 0.0 56 0 ? IW 00:41 0:00 cron
akira 172 0.0 1.4 32 196 p0 S 01:01 0:00 grep cron

上例中指令 set echo 的在顯示執行的指令。(set echo 是 shell 的一個預設變數在後面將會有詳細的說明)在例子中可清楚的看到設定 aliases 後所執行的 psg cron 情況,因為 psg=ps axu | grep,所以 psg cron 便相當於 ps axu | grep cron。實際上這個指令組合在 grep 的處理的並不完美,因為會連自己的 process 也顯示出來。所以我們將指令組合再加一道指令來去掉這個 bug。如下:

% ps axu | grep pattern | grep -v grep

用指令 grep -v grep 來去掉不需要的訊息。但如此一來 grep 所需 pattern 要如何帶入 aliases 的設定呢?這便是如何將下指令的引數帶入 aliases 的設定中。關於這種情況你可以運用以下這幾個特殊符號來導入所需的引數,以達到你所想要設定功能。

符號

說明

!*

代表指令行的第一個到最後一個引數

!^

代表指令行的第一個引數

!:n

代表指令行的第 n 個引數

所以關於上一個 aliases 設定,便可使用“!^”或“!:1”來帶入第一個引數。aliases 設定如下所列兩種方式均可:

% alias psg 'ps axu | grep \!^ | grep -v grep'
% alias psg 'ps axu | grep \!:1 | grep -v grep'

如果要同時運用多個引數,我們以常用的 find 指令複雜的運用來做為例子,如下:

% find path -name filename -type f rm -i {} \;
% alias ffrm 'find \!:1 -name \!:2 -type f rm -i {} \;'
% ffrm / cshrc.old

如果要同時將所有引數全部帶入且無法預期引數的數量,符號“!*”正好符合需求,例如:

% chmod u+x filenames
% alias cux 'chmod u+x \!*'
% ls -l dirnames | grep "^d"
% alias lsd 'ls \!* | grep "^d"

(這個例子中的 grep "^d" 是指每行開頭的第一個字母為 d,才顯示。整個指令組合運用來顯示指定目錄下層子目錄。)

 

3-6-2 別名設定中引用別名

 

在 aliases 設定的指令組合中允許使用已設定的 aliases。如下說明:

% alias a alias
% a h history
% a hten 'h | head -10'

第一行設定 a = alias,第二行馬上運用第一行所設定的 a = alias 來設定 h = history,第三行中則運用了第一行及第二行的的設定。像此類的設定雖然成立,但實際運用時可得小心。

 

3-6-3 別名設定的迴圈錯誤(alias loop)現象

% alias date 'clear;date'
% date
Alias loop.
% alias ps 'who; ps'
% ps
Alias loop.

看看上面這幾個 aliases 的設定,雖然在語法上是合理的,設定時也不會產生錯誤訊息,但為何執行時卻都會產生錯誤呢?請仔細想想看!其實原因均是在“指令組合”中運用連續指令時產生的,其現象就是當 aliases 的名稱與所設定的 aliases 內容的最後一個指令相同所造成的。請特別注意下例的ps:

% alias ps 'who; ps'

展開來執行 ps 便等於 who; ps,而連續指令中的 ps 會因為 aliases 已設定成功的因素,也等於who ; ps,如此設定後的 ps 在執行時便會產生一個怪異的結果,也就是一直在執行who ; who ; ...,這就是所謂的 Alias loop.

要避開 Alias loop. 有幾種方式,可將指令組合中的指令改為絕對路徑,如下:

% alias ps 'who; /bin/ps'

同理但迅速的方法便是利用符號“\”,如下所示:

% alias ps 'who; \ps'

以上的兩個避開 Alias loop. 的方法,如果碰到要使用 C Shell 的內建指令,就無效了。這時您可以嘗試將指令組合中的指令,次序上對調如下亦可解除“Alias loop.”的情況。(雖然看起來也像會造成執行的迴圈,但其實不會,請放心使用)

% alias ps 'ps;who'

在前面我們提過 alias 與指令名稱相衝的情況是可允許的,但也是必須要加以特別小心的。因為在 alias 設定中你可能一不小心便造成這種錯得不知不覺的情況產生。同時別名與指令名稱相沖的情況,最容易影響到設計考慮不週全的 shell script,造成執行錯誤或增加移植上的困擾。此點不可不慎重其事。

3-6-4 幾個實用的別名實例

好的 aliases 設定往往會令人錯覺是一個“新指令”的誕生。而 aliases 的設定方式也可說是千奇百怪,花招無窮。每當我想到或看到有創意的 aliases 時,總不免惹人一笑。我們來看看下面所列的幾個 aliases 的例子:

alias vicsh 'vi \!:1 ; chmod u+x \!:1'

上面這個 aliase 是將指令 vi 與 chmod 的功能結合在一起,用來免除我們用 vi 編輯器編寫一個新的 C Shell 程式時,還要自己再用指令 chmod 來改便該檔案的“執行權限”的使用困擾。這對常撰寫 C Shell 程式的使用者來說真的相當方便。

alias cd 'cd \!*;set prompt = "\! <$cwd> "'

 

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