一、指令的别名、Shell 函數
記住所有的指令及各自帶的可選項,然後每次一一輸入,這确實有點枯燥。但幸運的是,您可以為常用指令定義快捷方式。這些快捷方式可以用較簡單的指令别名(alias),或複雜一些的 shell 函數的文法來定義。
1、指令的别名
例如,我用下面的指令來上傳 MUO 中的檔案:
rsync -e ssh -z -t -r -vv --progress /home/tom/web/muo/rsmuo/docs muo:/www/mandrakeuser/docs
顯然,如果每次都要逐一輸入,那我早晚會變成木頭。是以我在'~/.bashrc'中定義了别名:
alias upmuo='rsync -e ssh -z -t -r -vv --progress /home/tom/web/muo/rsmuo/docs muo:/www/mandrakeuser/docs'
現在,我隻要輸入 upmuo 就可以完成上傳任務了。
定義别名的文法是:
alias shortcut='command'
指令中有空格的話 ,就需要用引号(如在指令與可選項間就有空格)。請注意,您可以用單引号或雙引号,但他們是有差別的。
單引号将剝奪其中的所有字元的特殊含義,而雙引号中的'$'(參數替換)和'`'(指令替換)是例外。這意味着,如果您想在别名中應用變量或指令的替換,就得用雙引号。看一下上面的例子,我在'.bashrc'中定義了一個稱為 MUOHOME 的變量:
export MUOHOME=$HOME/web/muo/rsmuo/docs
要在上面的别名中用上這個變量,我就必須用雙引号:
alias upmuo="rsync -e ssh -z -t -r -vv --progress $MUOHOME muo:/www/mandrakeuser/docs"
否則,别名将查找一個名為'$MUOHOME'的目錄或檔案。
您可以用'alias'在指令行快速地建立别名,或将指令放到各自的'~/.bashrc',或放到系統級的'/etc/profile.d/alias.sh'中(而在 Mandrake Linux 8 以前的版本裡,用的是'/etc/bashrc')。要删除一個别名,隻要輸入:unalias alias 。運作 alias 将列出您系統中所有定義的别名。
如果看一下'~/.bashrc'和'/etc/profile.d/alias.sh',您會發現系統已經定義了一些别名。您可以為同一個指令定義多個别名。當然,您得先确認别名與其他程式名不同,比如象 alias rm='ls -l' 這樣的就不能工作。您可以在指令行輸入這些快捷方式,測試一下。如果 shell 找不到相同名稱的指令,那您就可以将其用作别名了。
以下别名可能有用(不要忘了引号!) :
l alias rpmq='rpm -qa | grep' :現在 rpmq string 就将列出所有名稱中含有 string 的已安裝 RPM 包,
l alias ls='ls -ho --color | more' :ls 将以彩色分頁方式列出檔案,檔案大小以 KB為機關,
l alias use='du --max-depth=1 | sort -n | more' :use 将子目錄按大小排好,并以分頁方式列出,
目錄的别名也可以是可移動的媒體:alias dlm='/mnt/cdrom/RedHat/RPMS/' 。
提示:将有相似功能的别名以相同字母開頭,比如将所有目錄的别名以'd'作開頭,這樣有助于記憶。
我相信,您将會用到這些功能。
2、Shell 函數
寫 shell 函數涉及到了 shell 腳本,這超出了我們讨論的範圍(也不在我的掌握範圍之内 ;-))。事實上,shell 函數屬于 shell 腳本,但可以在同一 shell 下被預加載(preload)和執行(而一般的 shell 腳本至少要打開一個 sub-shell)。
通過 shell 函數,您可以做很多 aliases 無法完成的事情。下面就是一個例子:
function apros() { apropos $1 | egrep -v '(3|/(n/)'; }
定義了一個新指令,稱為'apros'。apros name 将先執行'apropos name'(即在 man page 中搜尋指令),然後将得到的輸出送到管道(|),接着用'egrep'過濾,排除第'3'和第'n'章節的 man page ,這個指令可能沒什麼大用處,但可以整理'apropos'指令的輸出。
函數允許您在函數内部任何位置,使用運作時的參數。而别名,則隻允許在指令行尾放一個參數(比如前面的别名'rpmq')。
'$1'就是位置參數(positional parameter),表示函數第一個參數的位置辨別符。依此類推,還有'$2'等。
function apros() { apropos $1 | egrep -v "/($2"; }
如果您這樣運作'apros'指令:
apros name man_section_number
這個指令将搜尋标題中含 name 的 man pages ,但排除 man_section_number 部分:
apros menu 3
将搜尋标題含'menu'的 man page ,但排除第三章節(關于程式設計的)。注意到您得引用(quote) 兩次,而且還用到了雙引号:
l 您必須引用'egrep'的搜尋模式,這樣可以不至于被 shell 誤解。
l 您必須用雙引号,這樣第二個參數才能被正确解釋。
l 您必須引用圓括号,這樣使'egrep'按字面意思對待對待參數。
是不是有點意思?;-)
shell 函數的處理類似于别名:将其放到您的'.bashrc'檔案,這樣就能永久生效了。
二、從這裡出發
我們談到的隻是 shell 的一個開頭。掌握了shell 腳本,您就可以做很多事情,比如将任務自動化,糾正别人腳本中的錯誤,按照您的習慣定制 Linux 系統。如果您打算學習某種複雜的程式設計語言,那 shell 腳本也是一個很好的開端,因為基本概念都是類似的。
BASH Programming - Introduction HOW-TO:
http://www.ibiblio.org/mdw/HOWTO/Bash-Prog-Intro-HOWTO.html
将更深入這些主題,并且将把您帶到 shell 程式設計的世界。然後可以繼續閱讀我強烈推薦的 Advanced Bash-Scripting Guide( http://www.ibiblio.org/mdw/LDP/abs/html/index.html ),作者是:Mendel Cooper 。
如果您偏好紙書,那我推薦 S. Veeraraghavan 的《Teach Yourself Shell Programming》,Sams 出版社。我倒覺得 O'Reilly 公司由 Newham/Rosenblatt 寫的《Learning the bash Shell》,不過爾爾,但這可能隻有我這麼看 ;-) 。
除了這些,就是練習,練習,再練習。閱讀其他人寫的 shell 腳本,看看他們在做什麼,怎麼做,為什麼那樣做。
請不要用'root'測試您的腳本。Have fun 。
關于本文
flaboy兄當時整理時發在了LinuxSir.Org 論壇 SHELL讨論區中,是作為SHELL 基礎教材的形式帖出的,他在整理時“本文編譯整理時對相關章節做了相應的删改處理,去掉了針對Mandrake Linux的部分内容。”;
我看這個文檔極其不錯,進行了再次整理,并對文檔的結構進行了調整,根據文檔的内容,我适當的加了序列号,并做了一個目錄,主要是友善大家閱讀;感謝原作者及中譯者,同時也感謝flaboy兄的整理;
我想整理文檔也是件比較幸福的事情,至少在看文檔的時候,我能知道有哪些是比較關健的,也能得到我想要學的東西,是以我會一直整理文檔;如果時間允許并有能力的話,我也會寫一些。── 北南南北
整理文檔是沒任何技術含量的,為什麼你會做呢?
雖然沒有技術含量,但我想如果能為他人帶來一點點友善,我想我所做的還是值得的,相對原創者和中譯者來說,我做的又算什麼呢?