在這之前,我們已經知道了一系列神秘的命令,每個命令都有自己奇妙的 選項和參數。在這一章中,我們將試圖去掉一些神秘性,甚至創建我們自己 的命令。這一章將介紹以下命令:
> * type – 說明怎樣解釋一個命令名
> * which – 顯示會執行哪個可執行程序
> * man – 顯示命令手冊頁
> * apropos – 顯示一系列適合的命令
> * info – 顯示命令 info
> * whatis – 顯示一個命令的簡潔描述
> * alias – 創建命令別名
## 到底什么是命令?
命令可以是下面四種形式之一:
1. 是一個可執行程序,就像我們所看到的位于目錄/usr/bin 中的文件一樣。 屬于這一類的程序,可以編譯成二進制文件,諸如用 C 和 C++語言寫成的程序, 也可以是由腳本語言寫成的程序,比如說 shell,perl,python,ruby,等等。
2. 是一個內建于 shell 自身的命令。bash 支持若干命令,內部叫做 shell 內部命令 (builtins)。例如,cd 命令,就是一個 shell 內部命令。
3. 是一個 shell 函數。這些是小規模的 shell 腳本,它們混合到環境變量中。 在后續的章節里,我們將討論配置環境變量以及書寫 shell 函數。但是現在, 僅僅意識到它們的存在就可以了。
4. 是一個命令別名。我們可以定義自己的命令,建立在其它命令之上。
## 識別命令
這經常很有用,能確切地知道正在使用四類命令中的哪一類。Linux 提供了一對方法來 弄明白命令類型。
## type - 顯示命令的類型
type 命令是 shell 內部命令,它會顯示命令的類別,給出一個特定的命令名(做為參數)。 它像這樣工作:
~~~
type command
~~~
“command”是你要檢測的命令名。這里有些例子:
~~~
[me@linuxbox ~]$ type type
type is a shell builtins
[me@linuxbox ~]$ type ls
ls is aliased to `ls --color=tty`
[me@linuxbox ~]$ type cp
cp is /bin/cp
~~~
我們看到這三個不同命令的檢測結果。注意,ls 命令(在 Fedora 系統中)的檢查結果,ls 命令實際上 是 ls 命令加上選項”--color=tty”的別名。現在我們知道為什么 ls 的輸出結果是有顏色的!
## which - 顯示一個可執行程序的位置
有時候在一個操作系統中,不只安裝了可執行程序的一個版本。然而在桌面系統中,這并不普遍, 但在大型服務器中,卻很平常。為了確定所給定的執行程序的準確位置,使用 which 命令:
~~~
[me@linuxbox ~]$ which ls
/bin/ls
~~~
這個命令只對可執行程序有效,不包括內部命令和命令別名,別名是真正的可執行程序的替代物。 當我們試著使用 shell 內部命令時,例如,cd 命令,我們或者得不到回應,或者是個錯誤信息:
~~~
[me@linuxbox ~]$ which cd
/usr/bin/which: no cd in
(/opt/jre1.6.0_03/bin:/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/opt/jre1
.6.0_03/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/home/me/bin)
~~~
說“命令沒有找到”,真是很奇特。
## 得到命令文檔
知道了什么是命令,現在我們來尋找每一類命令的可得到的文檔。
## help - 得到 shell 內部命令的幫助文檔
bash 有一個內建的幫助工具,可供每一個 shell 內部命令使用。輸入“help”,接著是 shell 內部命令名。例如:
~~~
[me@linuxbox ~]$ help cd
cd: cd [-L|-P] [dir]
Change ...
~~~
注意表示法:出現在命令語法說明中的方括號,表示可選的項目。一個豎杠字符 表示互斥選項。在上面 cd 命令的例子中:
~~~
cd [-L|-P] [dir]
~~~
這種表示法說明,cd 命令可能有一個“-L”選項或者“-P”選項,進一步,可能有參數“dir”。
雖然 cd 命令的幫助文檔很簡潔準確,但它決不是教材。正如我們所看到的,它似乎提到了許多 我們還沒有談論到的東西!不要擔心,我們會學到的。
## --help - 顯示用法信息
許多可執行程序支持一個 --help 選項,這個選項是顯示命令所支持的語法和選項說明。例如:
~~~
[me@linuxbox ~]$ mkdir --help
Usage: mkdir [OPTION] DIRECTORY...
Create ...
~~~
一些程序不支持 --help 選項,但不管怎樣試一下。這經常會導致輸出錯誤信息,但同時能 揭示一樣的命令用法信息。
## man - 顯示程序手冊頁
許多希望被命令行使用的可執行程序,提供了一個正式的文檔,叫做手冊或手冊頁(man page)。一個特殊的叫做 man 的分頁程序,可用來瀏覽他們。它是這樣使用的:
~~~
man program
~~~
“program”是要瀏覽的命令名。
手冊文檔的格式有點不同,一般地包含一個標題,命令語法的綱要,命令用途的說明, 和命令選項列表,及每個選項的說明。然而,通常手冊文檔并不包含實例,它打算 作為一本參考手冊,而不是教材。作為一個例子,瀏覽一下 ls 命令的手冊文檔:
~~~
[me@linuxbox ~]$ man ls
~~~
在大多數 Linux 系統中,man 使用 less 工具來顯示參考手冊,所以當瀏覽文檔時,你所熟悉的 less 命令都能有效。
man 所顯示的參考手冊,被分成幾個章節,它們不僅僅包括用戶命令,也包括系統管理員 命令,程序接口,文件格式等等。下表描繪了手冊的布局:
表6-1: 手冊頁的組織形式
| 章節 | 內容 |
| --- | --- |
| 1 | 用戶命令 |
| 2 | 程序接口內核系統調用 |
| 3 | C 庫函數程序接口 |
| 4 | 特殊文件,比如說設備結點和驅動程序 |
| 5 | 文件格式 |
| 6 | 游戲娛樂,如屏幕保護程序 |
| 7 | 其他方面 |
| 8 | 系統管理員命令 |
有時候,我們需要查看參考手冊的特定章節,從而找到我們需要的信息。 如果我們要查找一種文件格式,而同時它也是一個命令名時,這種情況尤其正確。 沒有指定章節號,我們總是得到第一個匹配項,可能在第一章節。我們這樣使用 man 命令, 來指定章節號:
~~~
man section search_term
~~~
例如:
~~~
[me@linuxbox ~]$ man 5 passwd
~~~
命令運行結果會顯示文件 /etc/passwd 的文件格式說明手冊。
## apropos - 顯示適當的命令
也有可能搜索參考手冊列表,基于某個關鍵字的匹配項。雖然很粗糙但有時很有用。 下面是一個以”floppy”為關鍵詞來搜索參考手冊的例子:
~~~
[me@linuxbox ~]$ apropos floppy
create_floppy_devices (8) - udev callout to create all possible
...
~~~
輸出結果每行的第一個字段是手冊頁的名字,第二個字段展示章節。注意,man 命令加上”-k”選項, 和 apropos 完成一樣的功能。
## whatis - 顯示非常簡潔的命令說明
whatis 程序顯示匹配特定關鍵字的手冊頁的名字和一行命令說明:
> 最晦澀難懂的手冊頁
>
> 正如我們所看到的,Linux 和類 Unix 的系統提供的手冊頁,只是打算作為參考手冊使用, 而不是教材。許多手冊頁都很難閱讀,但是我認為由于閱讀難度而能拿到特等獎的手冊頁應該是 bash 手冊頁。因為我正在為這本書做我的研究,所以我很仔細地瀏覽了整個 bash 手冊,為的是確保我講述了 大部分的 bash 主題。當把 bash 參考手冊整個打印出來,其篇幅有八十多頁且內容極其緊密, 但對于初學者來說,其結構安排毫無意義。
>
> 另一方面,bash 參考手冊的內容非常簡明精確,同時也非常完善。所以,如果你有膽量就查看一下, 并且期望有一天你能讀懂它。
## info - 顯示程序 Info 條目
GNU 項目提供了一個命令程序手冊頁的替代物,稱為”info”。info 內容可通過 info 閱讀器 程序讀取。info 頁是超級鏈接形式的,和網頁很相似。這有個例子:
~~~
File: coreutils.info, Node: ls invocation, Next: dir invocation,
Up: Directory listing
10.1 `ls': List directory contents
==================================
...
~~~
info 程序讀取 info 文件,info 文件是樹型結構,分化為各個結點,每一個包含一個題目。 info 文件包含超級鏈接,它可以讓你從一個結點跳到另一個結點。一個超級鏈接可通過 它開頭的星號來辨別出來,把光標放在它上面并按下 enter 鍵,就可以激活它。
輸入”info”,接著輸入程序名稱,啟動 info。下表中的命令,當顯示一個 info 頁面時, 用來控制閱讀器。
表 6-2: info 命令
| 命令 | 行為 |
| --- | --- |
| ? | 顯示命令幫助 |
| PgUp or Backspace | 顯示上一頁 |
| PgDn or Space | 顯示下一頁 |
| n | 下一個 - 顯示下一個結點 |
| p | 上一個 - 顯示上一個結點 |
| u | Up - 顯示當前所顯示結點的父結點,通常是個菜單 |
| Enter | 激活光標位置下的超級鏈接 |
| q | 退出 |
到目前為止,我們所討論的大多數命令行程序,屬于 GNU 項目”coreutils”包,所以輸入:
~~~
[me@linuxbox ~]$ info coreutils
~~~
將會顯示一個包含超級鏈接的手冊頁,這些超級鏈接指向包含在 coreutils 包中的各個程序。
## README 和其它程序文檔
許多安裝在你系統中的軟件,都有自己的文檔文件,這些文件位于/usr/share/doc 目錄下。 這些文件大多數是以文本文件的形式存儲的,可用 less 閱讀器來瀏覽。一些文件是 HTML 格式, 可用網頁瀏覽器來閱讀。我們可能遇到許多以”.gz”結尾的文件。這表示 gzip 壓縮程序 已經壓縮了這些程序。gzip 軟件包包括一個特殊的 less 版本,叫做 zless,zless 可以顯示由 gzip 壓縮的文本文件的內容。
## 用別名(alias)創建你自己的命令
現在是時候,感受第一次編程經歷了!我們將用 alias 命令創建我們自己的命令。但在 開始之前,我們需要展示一個命令行小技巧。可以把多個命令放在同一行上,命令之間 用”;”分開。它像這樣工作:
~~~
command1; command2; command3...
~~~
我們會用到下面的例子:
~~~
[me@linuxbox ~]$ cd /usr; ls; cd -
bin games kerberos lib64 local share tmp
...
[me@linuxbox ~]$
~~~
正如我們看到的,我們在一行上聯合了三個命令。首先更改目錄到/usr,然后列出目錄 內容,最后回到原始目錄(用命令”cd ~”),結束在開始的地方。現在,通過 alia 命令 把這一串命令轉變為一個命令。我們要做的第一件事就是為我們的新命令構想一個名字。 比方說”test”。在使用”test”之前,查明是否”test”命令名已經存在系統中,是個很不錯 的主意。為了查清此事,可以使用 type 命令:
~~~
[me@linuxbox ~]$ type test
test is a shell builtin
~~~
哦!”test”名字已經被使用了。試一下”foo”:
~~~
[me@linuxbox ~]$ type foo
bash: type: foo: not found
~~~
太棒了!”foo”還沒被占用。創建命令別名:
~~~
[me@linuxbox ~]$ alias foo='cd /usr; ls; cd -'
~~~
注意命令結構:
~~~
alias name='string'
~~~
在命令”alias”之后,輸入“name”,緊接著(沒有空格)是一個等號,等號之后是 一串用引號引起的字符串,字符串的內容要賦值給 name。我們定義了別名之后, 這個命令別名可以使用在任何地方。試一下:
~~~
[me@linuxbox ~]$ foo
bin games kerberos lib64 local share tmp
...
[me@linuxbox ~]$
~~~
我們也可以使用 type 命令來查看我們的別名:
~~~
[me@linuxbox ~]$ type foo
foo is aliased to `cd /usr; ls ; cd -'
~~~
刪除別名,使用 unalias 命令,像這樣:
~~~
[me@linuxbox ~]$ unalias foo
[me@linuxbox ~]$ type foo
bash: type: foo: not found
~~~
雖然我們有意避免使用已經存在的命令名來命名我們的別名,但這是常做的事情。通常, 會把一個普遍用到的選項加到一個經常使用的命令后面。例如,之前見到的 ls 命令,會 帶有色彩支持:
~~~
[me@linuxbox ~]$ type ls
ls is aliased to 'ls --color=tty'
~~~
要查看所有定義在系統環境中的別名,使用不帶參數的 alias 命令。下面在 Fedora 系統中 默認定義的別名。試著弄明白,它們是做什么的:
~~~
[me@linuxbox ~]$ alias
alias l.='ls -d .* --color=tty'
...
~~~
在命令行中定義別名有點兒小問題。當你的 shell 會話結束時,它們會消失。隨后的章節里, 我們會了解怎樣把自己的別名添加到文件中去,每次我們登錄系統,這些文件會建立系統環境。 現在,好好享受我們剛經歷過的,步入 shell 編程世界的第一步吧,雖然微小。
## 拜訪老朋友
既然我們已經學習了怎樣找到命令的幫助文檔,那就試著查閱,到目前為止,我們學到的所有 命令的文檔。學習命令其它可用的選項,練習一下!
## 拓展閱讀
* 在網上,有許多關于 Linux 和命令行的文檔。以下是一些最好的文檔:
* Bash 參考手冊是一本 bash shell 的參考指南。它仍然是一本參考書,但是包含了很多 實例,而且它比 bash 手冊頁容易閱讀。
[http://www.gnu.org/software/bash/manual/bashref.html](http://www.gnu.org/software/bash/manual/bashref.html)
* Bash FAQ 包含關于 bash,而經常提到的問題的答案。這個列表面向 bash 的中高級用戶, 但它包含了許多有幫助的信息。
[http://mywiki.wooledge.org/BashFAQ](http://mywiki.wooledge.org/BashFAQ)
* GUN 項目為它的程序提供了大量的文檔,這些文檔組成了 Linux 命令行實驗的核心。 這里你可以看到一個完整的列表:
[http://www.gnu.org/manual/manual.html](http://www.gnu.org/manual/manual.html)
* Wikipedia 有一篇關于手冊頁的有趣文章:
[http://en.wikipedia.org/wiki/Man_page](http://en.wikipedia.org/wiki/Man_page)
- 第一章:引言
- 第二章:什么是shell
- 第三章:文件系統中跳轉
- 第四章:研究操作系統
- 第五章:操作文件和目錄
- 第六章:使用命令
- 第七章:重定向
- 第八章:從shell眼中看世界
- 第九章:鍵盤高級操作技巧
- 第十章:權限
- 第十一章:進程
- 第十二章:shell環境
- 第十三章:VI簡介
- 第十四章:自定制shell提示符
- 第十五章:軟件包管理
- 第十六章:存儲媒介
- 第十七章:網絡系統
- 第十八章:查找文件
- 第十九章:歸檔和備份
- 第二十章:正則表達式
- 第二十一章:文本處理
- 第二十二章:格式化輸出
- 第二十三章:打印
- 第二十四章:編譯程序
- 第二十五章:編寫第一個shell腳本
- 第二十六章:啟動一個項目
- 第二十七章:自頂向下設計
- 第二十八章:流程控制 if分支結構
- 第二十九章:讀取鍵盤輸入
- 第三十章:流程控制 while/until 循環
- 第三十一章:疑難排解
- 第三十二章:流程控制 case分支
- 第三十三章:位置參數
- 第三十四章:流程控制 for循環
- 第三十五章:字符串和數字
- 第三十六章:數組
- 第三十七章:奇珍異寶