一、SHELL 的功能及分類

SHELL是UNIX作業系統中的'命令編譯器'(Command Interpreter),它 基本上是一個常駐的執行程式,它在使用者一簽入成功後就立即被載入、 執行,這可在您簽入後以 ps 指令看到,它主要功能則在於接受使用者的 指令、尋找命令(即執行檔)的所在並加以執行。

因此,SHELL 的不同可能直接影響使用者輸入指令的方式、檔案尋找 的程序及速度等,對使用者的影響是相當直接的。

UNIX作業系統的SHELL 大致可分為兩大系統,一是1970年代前期由美 國貝爾實驗室(BELL LAB)所發展的sh(Bourne Shell),它是UNIX系統中的 標準SHELL,此一系統後來又發展出ksh(Korne Shell)、bash(Bourne Again Shell)等功能更多的介面;另一系統是美國柏克來大學(Berkeley)在1970 年代後期所發展的csh(C Shell),和它屬於同一系統的有tcsh等。

無論上述的那一種shell ,它的基本功能與作用都是相同的,它們之 間的不同處可能在於對同一動作處理程序上的不同(會影響命令處理的速 度)、所提供內鍵命令及變數的或多或寡等,其中內部命令與變數的多寡 直接影響到shell 功能的多寡,是使用者在使用時最容易直接感受到的。

在UNIX系統中,使用者可視自己的需要執行sh、ksh、bash 、csh 或 tcsh來代替原先使用的shell 、改變正在使用的環境;或是利用 chsh 指 令,改變login 時所使用的shell ,如:

New shell: (輸入想使用的shell的路徑及名稱,如/bin/csh)

如此,可使自己所使用的環境最滿足自己使用上的需要。

備註:

  1. 1. 在Oz Domain 上使用chsh還需輸入個人使用者的密碼。
  2. 2. Login 時可使用的shell 及其路徑可參考檔案 /etc/shells。

二、SHELL 的Start Files

不管你的Login Shell 是那一種shell,每一個shell都有它自己的 Start Files ,我們設定理想環境時所需使用的指令與變數的設定,都可 以寫在這些 Start Files中,在login 時就加以執行或設定,這些 Start Files 的名稱分別是:
		SHELLs	       Start Files
		───	       ──────
		sh	       /etc/profile
			       $HOME/.profile
		bash	       /etc/profile
			       $HOME/.profile(or $HOME/.bashrc)
		csh	       None
			       $HOME/.cshrc & $HOME/.login
		tcsh	       None
			       $HOME/.cshrc(or $HOME/.tcshrc)
			       & $HOME/.login
如果這些檔案都存在,那麼它們的執行順序將是:

  1. sh系列
    /etc/profile --> $HOME/.profile
  2. csh系列
    $HOME/.cshrc --> $HOME/.login

在這些 Start Files中,/etc下的 profile是系統管理者為大家設定 的,一般使用者無法做任何更動,如果對系統管理者的設定覺得不夠或不 符需求,則可在個人帳號下的.profile、.cshrc、.login增加或修正,尤 其是對csh 及 tcsh 的使用者而言,因為在/etc下並沒有 Start Files, 所以也不會有系統管理者設定好的環境可以使用,使用者就必須自行設定 所需要的所有的變數與指令,否則常會有寸步難行的感覺,最常見的如許 多指令都因找不到而不能執行,如執行 elm,卻被告知:

elm: command not found.

這是因為沒有設path、或[backspace]鍵無法使用,而這則是因為 [backspace] 鍵的作用沒有定義之故。

三、常見的需求與常用的指令

當我們在UNIX環境中工作,常會為了使自己使用時更方便而產生某些 需求,這些常見的需求及其設定方式如:

  1. 希望[BACKSPACE] 鍵能有作用

    在$HOME/.profile或$HOME/.cshrc中加上 stty erase "^H" 其中"^H"是按[BACKSPACE] 鍵時在螢幕上所顯示的對應碼,它也可能 是"^?"或其他的對應碼。

  2. 希望在UNIX環境中能使用中文

    在$HOME/.profile(sh系列)中加上
    stty -istrip cs8
    LC_CTYPE=iso_8859_1
    export LC_CTYPE

    在$HOME/.cshrc(csh系列)中加上
    stty -istrip cs8
    setenv LC_CTYPE iso_8859_1

  3. 希望能有像DOS系統中DOSKEY的功能

    只要是使用bash及tcsh即具備此項功能。

  4. 希望能使用工作站上的漢書編輯器(he)

    在$HOME/.profile(sh系列)中加上
    HLANG=big5
    export HLANG

    在$HOME/.cshrc(csh系列)中加上
    setenv HLANG big5

  5. 希望提示符號能隨著路徑更動而改變

    在 sh 及 csh中並無法做到這個功能,而在 bash 及 tcsh 中的 設定則分別是:

    bash:在$HOME/.profile中加上
    PS1='`PWD`> '
    或 PS1="\w> "

    tcsh:在$HOME/.cshrc中加上
    set prompt='%~> '

除了上面所提到針對特殊需要所做的設定之外,在做環境設定時常用 到的指令還有:

  1. stty

    設定對輸入(input) 的定義與輸出的格式,這個指令的參數極為 眾多,我們可用

    stty -a

    看到所有的參數及其設定,在這些參數中,常用的有:

    istrip (-istrip)

    將所有的輸入截取成7 bits的資料,然而中文的資料都是8 bits 的,所以當需要使用中文時,請加上 -istrip這個參數,以避免 輸入的資料被破壞,如:

    stty -istrip

    cs7 cs8

    設定每一字元的資料都是7 bits或8 bits的資料,因此在需要使 用中文時,通常會有如下的設定:

    stty -istrip cs8

    iuclc (-iuclc)

    將標準輸入的大寫字母視為小寫(或取消),如此,使用者就無法 處理需要大寫的指令或目錄、檔案。
    olcuc (-olcuc)

    將小寫的字母以大寫型態輸出(或取消),如此,使用者在畫面上 看到的將都是大寫字母、無法分辯字母是真正的大寫、小寫。

    echo (-echo)

    將所有的輸入由標準輸出處輸出(或取消輸出),若將輸出取消, 在螢幕上看不到自己輸入的任何字元。

    stty除了這些參數外,還可以用來定義某一個鍵的特定功能,如:

    stty erase "^H"
    stty kill "^U"
  2. mesg y (mesg n)

    若在工作時不希望被talk等訊息所打擾,可下

    mesg n

    即可避免外來迅息中斷正在進行的工作,而mesg y則可重新恢復 與外界的溝通。

  3. umask [nnn]

    設定新增檔案或目錄的屬性(mode),新檔案或新目錄的mode為系 統管理者以create所設定的屬性減去 nnn,如系統管理者所設定的檔 案權利狀態是777,而使用者又自行設定了

    umask 022
    則這個使用者在他個人帳號下的每一個新產生的檔案的權利狀態都將 會是

    777 - 022 = 755
    另外,系統管理者所內定的檔案及目錄的屬性並不一定相同。
  4. Function 與 Alias

    對於一連串或某一指令,我們可以用function的方式(在sh 、 ksh 、bash 中)或 alias指令(在csh 、tcsh 、ksh 、bash 中),用 一簡短字串來代替這一個或一連串的指令,function的用法如:

    vi(){
    mesg n
    /usr/ucb/vi $*
    mesg y
    }

    其中, vi 是function的名稱, {} 之間是 vi 這個function所包含 的指令內容,而要注意的是:function的名稱不能與shell 的內鍵指 令(builtin) 名稱相同,否則這個function即無法成立。

    同樣的功能,alias 指令的用法如:

    alias vi "mesg n; /usr/ucb/vi \!*; mesg y"
    (在csh與tcsh中)
    alias vi="mesg n; /usr/ucb/vi $*; mesg y"
    (在bash中)

    其中 vi 即是 "" 中所包含的各指令的別名,而各指令間須以";" 隔 開,別名與各shell 的builtin 名稱可以一樣( alias 本身也是一個 內鍵指令)。

    若我們在某一shell 中同時建立一名稱相同的function與 alias (如在bash中),則 alias的執行次序優先於function的執行。

四、常用變數設定

在 UNIX 環境中的變數可分為兩類,一是 環境變數 - Enviroment Variable、一是 shell 變數 - Shell Variable,二者之間的不同處在: 環境變數不會因為shell 間的更替而失去這個變數的作用,如 PATH 是一 個環境變數,因此,即使您在設定好PATH之後再執行另一個 shell,如原 來是用sh、而後在sh環境中再執行 csh,則PATH這個環境變數仍可繼續在 新執行的shell 中發生作用。

而shell 變數(如csh 的 cwd)則是只有在特定的shell 下才有作用, 一旦執行其他shell ,這些變數就會失去作用。

sh 及 csh 系列的shells中各有其不同的設定變數的方式,為:

  1. Bourne Shell系列

    [VAR]=[STRING or NUMBER]
    export [VAR]
    如果當我們離開shell 、進入另一個程式(如 tin)之後,仍需要使用 這個變數,則除了設定這個變數的值外,還需要以 export 指令加以 宣告,如設定螢幕型態的變數TERM、設定tin 的編輯器的EDITOR等變 數均需以 export 來宣告。

  2. C Shell系列

    set [var]=[STRING or NUMBER]
    或 setenv [var] [STRING or NUMBER]

    其中set 是單純設定變數值, setenv 則除了設定變數值外,還包含 了類似sh中 export 指令的功能。

而無論是Bourne Shell或C Shell ,它們都有一些基本的、共同的常 用變數,如:

  1. PATH

    設定執行檔的尋找路徑,若現行目錄也要包含在尋找的路徑中, 則需在設定路徑時加上 . 這個路徑,表示現行目錄亦包含在尋找的 路徑中,如:

    PATH=.:/bin:/usr/local/bin:/usr/ucb

    set path=(. /bin /usr/local/bin /usr/ucb)

  2. EDITOR

    當使用tin 時,若需使用編輯器(如要貼公告時),tin 將參考 EDITOR變數的內容來決定要執行那一個編輯器,因此我們可以用下 列方式設定想要在tin 中使用的編輯器:

    EDITOR=/usr/ucb/vi
    export EDITOR

    setenv EDITOR /usr/ucb/vi

  3. HOME

    設定個人帳號Home Directory的所在位置,通常在login 時即參 考/etc/passwd 而加以設定,因此除非使用者有某些特殊需求,通常 不會重新設定。

  4. SHELL

    同樣是在login 時即會參考/etc/passwd 的內容而自動設定,最 大的功能在於讓使用者了解自己在Login 時最初使用的shell ,因即 使重新設定這個變數的內容,對帳號的使用也不會有任何影響。

  5. TERM

    設定終端機的螢幕顯示型態,以PC為終端機時TERM應設為VT100, 如: TERM=vt100
    export TERM

    setenv TERM vt100

  6. MANPATH

    設定指令的man page的尋找路徑,如:
    MANPATH=/usr/lib/man:/usr/man

  7. LC_CTYPE

    設定輸出的CODE PAGE,若需使用中文則需設定為:
    LC_CTYPE=iso_8859_1
    export LC_CTYPE

    setenv LC_CTYPE iso_8859_1

  8. 提示符號的設定

    在sh 系列中:
    PS1="[STRING]"
    PS2="[STRING]"

    在csh中:
    set prompt="[STRING]"

當然以上所列的只是使用得較為廣泛的變數,若您覺得這些不夠用, 可用 man sh、man csh、man tcsh、man bash指令查閱各shell 的說明, 在其中您將可看到各個shell 所包含的變數及各變數的用法。

若不清楚某一變數的設定內容,可用

echo $[VAR]
來觀察變數的內容,如:
echo $PATH

五、SHELL 環境的異動

前面所提到Start Files中的設定將在使用者login 時執行, 但當我們要在線上直接改變正在使用的shell 或環境設定時,則 在編修了Start Files或Script Files之後,可利用下列指令將 環境更新,而不必重新login :

在 sh 系列的shell 中

. [Script File]
在csh 系列的shell 中

source [Script File]
直接執行一個Script File 與用 . 、 source 指令執行各有其不同 的效果,我們可建立一內容為

cd /
ls -al
的Script File 來觀察它們之間的差異:

因Script File 的執行環境是一內定或自定的subshell、這可在 Script File 的第一行用類似

#!/bin/csh
的方式加以設定,所以一個Script File 的直接執行並無法真正 將shell 環境的工作目錄切換到/ 下,而script file 一結束, subshell也即告結束、 cd / 指令的執行效果也跟著subshell的 結束而告消失,現有環境中的現行路徑的位置仍與未執行Script File前一樣。

而如果我們用 . 或 source 來執行一個Script File ,則Script File中指令的執行與變數的設定即都在現有環境中執行、而真正 改變shell 本身的設定,Script File 中指令的效果不會因為 Script file 的結束而消失,如前述例子,現有環境的工作目錄 將會真正切換到 / 下。