3.9. Shell

Shell 提供了指令列介面可用來與作業系統互動,Shell 負責從輸入的頻道接收指令並執行它們。 多數 Shell 也內建一些有助於日常工作的功能,像是檔案管理、檔案搜尋、指令列編輯、指令巨集以及環境變數等。 FreeBSD 有內附了幾個 Shell,包含 Bourne Shell (sh(1)),與改良版的 C-shell (tcsh(1))。 還有許多其他的 Shell 可以從 FreeBSD Port 套件集中取得,像是 zsh 以及 bash 等。

要用哪個 Shell 牽涉到每個人的喜好。 如果您是一個 C 程式設計師,那對於使用像是 tcsh(1) 這種 C-like 的 shell 可能會感到較容易上手。 如果是 Linux® 的使用者,那您也許會想要用 bash。 每一個 Shell 都有自已獨特之處,至於這些特點能不能符合使用者的喜好,就是您選擇 shell 的重點了。

常見的 Shell 功能之一就是檔名自動補齊。 首先輸入指令或檔案的前幾個字母,然後按下 Tab 鍵,Shell 就會自動把指令或是檔案名稱剩餘的部份補齊。 假設您有兩個檔案分別叫作 foobarfootball。 要刪掉 foobar,那麼可以輸入 rm foo 然後按下 Tab 來補齊檔名。

但 Shell 只顯示了 rm foo,這代表它沒有辦法完全自動補齊檔名,因為有不只一個檔名符合條件。 foobarfootball 都是 foo 開頭的檔名。 有一些 Shell 會有嗶的音效或者顯示所有符符條件的檔名。 使用者只需要多打幾個字元來分辦想要的檔名。 輸入 t 然後再按 Tab 一次,那 Shell 就能夠替您把剩下的檔名填滿了。

Shell 的另一項特點是使用了環境變數。 環境變數是以變數與鍵值 (variable/key) 的對應關係儲存於 Shell 的環境,任何由該 Shell 所產生的程序都可以讀取此環境變數, 因此環境變數儲存了許多程序的設定。 表格 3.4, “常用環境變數” 提供了常見的環境變數與其涵義的清單。 請注意環境變數的名稱永遠以大寫表示。

表格 3.4. 常用環境變數
變數說明
USER目前登入的使用者名稱。
PATH以冒號 (:) 隔開的目錄列表,用以搜尋執行檔的路徑。
DISPLAY若存在這個環境變數,則代表 Xorg 顯示器的網路名稱。
SHELL目前使用的 Shell。
TERM使用者終端機類型的名稱,用來判斷終端機有那些功能。
TERMCAP用來執行各種終端機功能的終端機跳脫碼 (Terminal escape code) 的資料庫項目。
OSTYPE作業系統的類型。
MACHTYPE系統的 CPU 架構。
EDITOR使用者偏好的文字編輯器。
PAGER使用者偏好的文字分頁檢視工具。
MANPATH以冒號 (:) 隔開的目錄列表,用以搜尋使用手冊的路徑。

在不同的 Shell 底下設定環境變數的方式也有所不同。 在 tcsh(1)csh(1),使用 setenv 來設定環境變數。 在 sh(1)bash 則使用 export 來設定目前環境的變數。 以下範例將 tcsh(1) Shell 下的 EDITOR 環境變數從預設值更改為 /usr/local/bin/emacs

% setenv EDITOR /usr/local/bin/emacs

相同功能的指令在 bash 下則是:

% export EDITOR="/usr/local/bin/emacs"

要展開以顯示目前環境變數中的值,只要在指令列輸入環境變數之前加上 $ 字元。 舉例來說,echo $TERM 會顯示出目前 $TERM 的設定值。

Shell 中有特殊字元用來表示特殊資料,我們將其稱作 Meta-characters。 其中最常見的 Meta-characters 是 * 字元,它代表了檔名中的任意字元。 Meta-characters 可以用在搜尋檔名,舉例來說,輸入 echo * 會和輸入 ls 得到幾乎相同的結果,這是因為 shell 會將所有符合 * 字元的檔案由 echo 顯示出來。

為了避免 Shell 轉譯這些特殊字元,我們可以在這些特殊字元前放一個反斜線 (\) 字元使他們跳脫 (Escape) Shell 的轉譯。舉例來說,echo $TERM 會印出你目前終端機的設定, echo \$TERM 則會直接印出 $TERM 這幾個字。

3.9.1. 變更 Shell

永久變更 Shell 最簡單的方法就是透過 chsh 指令。 執行 chsh 將會使用環境變數中 EDITOR 指定的文字編輯器,如果沒有設定,則預設是 vi(1)。 請修改 Shell: 為新的 Shell 的完整路徑。

或者,使用 chsh -s, 來直接設定 Shell 而不開啟文字編輯器。 例如, 假設想把 Shell 更改為 bash

% chsh -s /usr/local/bin/bash

注意:

新的 Shell 必須已列於 /etc/shells 裡頭。 若是依 章 4, 安裝應用程式: 套件與 Port 說明由 Port 套件集來裝的 Shell, 那就會自動列入至該檔案裡。 若仍缺少,請使用以下指令加入檔案 (請將路徑替換為新的 Shell 的路徑):

# echo /usr/local/bin/bash >> /etc/shells

然後重新執行 chsh(1)

3.9.2. 進階 Shell 技巧

Written by Tom Rhodes.

UNIX® Shell 不只是指令的直譯器,它是一個強大的工具可讓使用者執行指令、重新導向指令的輸出、重新導向指令的輸入並將指令串連在一起來改進最終指令的輸出結果。當這個功能與內建的指令混合使用時,可提供一個可以最佳化效率的環境給使用者。

Shell 重新導向是將一個指令的輸出或輸入傳送給另一個指令或檔案。例如,要擷取 ls(1) 指令的輸出到一個檔案,可以重新導向輸出:

% ls > directory_listing.txt

目錄的內容現在會列到 directory_listing.txt 中,部份指令可以讀取輸入,例如 sort(1)。要排序這個清單,可重新導向輸入:

% sort < directory_listing.txt

輸入的內容會被排序後呈現在畫面上,要重新導向該輸入到另一個檔案,可以重新導向 sort(1) 的出輸:

% sort < directory_listing.txt > sorted.txt

於上述所有的範例中,指令會透過檔案描述符 (File descriptor) 來執行重新導向。每個 UNIX® 系統都有檔案描述符,其中包含了標準輸入 (stdin)、標準輸出 (stdout) 以及標準錯誤 (stderr)。每一種檔案描述符都有特定的用途,輸入可能來自鍵盤或滑鼠、任何可能提供輸入的來源,輸出則可能是螢幕或印表機中的紙張,而錯誤則為任何可能用來診斷的資訊或錯誤訊息。這三種皆被認為是以 I/O 為基礎的檔案描述符,有些也會被當做串流。

透過使用這些檔案描述符,Shell 能夠讓輸出與輸入在各種指令間傳遞與重新導向到或自檔案。另一種重新導向的方式是使用管線運算子 (Pipe operator)。

UNIX® 的管線運算子,即 |,可允許指令的輸出可直接傳遞或導向到另一個程式。基本上,管線運算子允許指令的標準輸出以標準輸入傳遞給另一個指令,例如:

% cat directory_listing.txt | sort | less

在這個例子中,directory_listing.txt 的內容會被排序然後輸出傳遞給 less(1),這可讓使用者依自己的閱讀步調捲動輸出的結果,避免結果直接捲動出畫面。

本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。

關於本文件的問題,請洽詢 <doc@FreeBSD.org>。