Shell十三問 轉載於網路,稍加整理。 <! more (一) 為何叫做Shell? 我們知道電腦的運作不能離開硬體,但使用者卻無法直接對硬體作驅動, 硬體的驅動只能透過一個稱為"操作系統(Operating System)"的軟體來控管 ,事實上, 我們每天所談的linux , 嚴格來說只是一 ...
Shell十三問
轉載於網路,稍加整理。
(一) 為何叫做Shell?
我們知道電腦的運作不能離開硬體,但使用者卻無法直接對硬體作驅動,硬體的驅動只能透過一個稱為"操作系統(Operating System)"的軟體來控管,事實上, 我們每天所談的linux , 嚴格來說只是一個操作系統, 我們稱之為"核心(kernel)"。然而,從使用者的角度來說,使用者也沒辦法直接操作 kernel ,而是透過 kernel 的"外殼"程式,也就是所謂的 shell ,來與 kernel 溝通。這也正是 kernel 跟 shell 的形像命名關係。
從技術角度來說, shell 是一個使用者與系統的互動界面(interface),主要是讓使用者透過命令行(command line)來使用系統以完成工作。因此, shell 的最簡單的定義就是---命令解譯器(Command Interpreter):
- 將使用者的命令翻譯給核心處理,
- 同時,將核心處理結果翻譯給使用者
每次當我們完成系統登入(log in), 我們就取得一個互動模式的 shell , 也稱為 login shell或 primary shell。
若從進程(process)角度來說,我們在 shell 所下達的命令,均是 shell 所產生的子進程。這現像,我們暫可稱之為 fork 。
如果是執行腳本(shell script)的話,腳本中的命令則是由另外一個非互動模式的子 shell(sub shell)來執行的。
也就是 primary shell 產生 sub shell 的進程, sub shell 再產生 script 中所有命令的進程。
(二) shell prompt(PS1) 與 Carriage Return(CR) 的關係?
當你成功登錄進一個文字界面之後,大部份情形下,你會在熒幕上看到一個不斷閃爍的方塊或底線(視不同版本而別),我們稱之為游標(coursor)。
游標的作用就是告訴你接下來你從鍵盤輸入的按鍵所插入的位置,且每輸如一鍵游標便向右邊移動一個格子,若連續輸入太多的話,則自動接在下一行輸入。
假如你剛完成登錄還沒輸入任何按鍵之前,你所看到的游標所在位置的同一行的左邊部份,我們稱之為提示符號(prompt)。
提示符號的格式或因不同系統版本而各有不同,在 Linux 上,只需留意最接近游標的一個可見的提示符號,通常是如下兩者之一:
$:給一般使用者帳號使用
#:給 root (管理員)帳號使用
事實上, shell prompt 的意思很簡單:
- 是 shell 告訴使用者:您現在可以輸入命令行了。
我們可以說,使用者只有在得到 shell prompt 才能打命令行,而 cursor 是指示鍵盤在命令行所輸入的位置,使用者每輸入一個鍵, cursor 就往後移動一格,直到碰到命令行讀進 CR(Carriage Return,由 Enter 鍵產生)字元為止。
CR 的意思也很簡單:
- 是使用者告訴 shell:老兄你可以執行我的命令行了。
嚴格來說,所謂的命令行,就是在 shell prompt 與 CR 字元之間所輸入的文字。
系統可接受的命令名稱(command-name)可以從如下途徑獲得:
- 明確路徑所指定的外部命令
- 命令別名(alias)
- 自定功能(function)
- shell 內建命令(built-in)
- $PATH 之下的外部命令
每一個命令行均必須含用命令名稱,這是不能缺少的。
echo知多少?
echo
是一個非常簡單、直接的 Linux 命令:
將 argument 送出至標準輸出(STDOUT),通常就是在監視器(monitor)上輸出。
先運行一下echo
命令:
$ echo
$
會發現只有一個空白行,然後又回到 shell prompt 上了。
這是因為 echo
在預設上,在顯示完 argument 之後,還會送出一個換行符號(new-line
charactor)。
但是上面的 command 並沒任何的 argument ,那結果就只剩一個換行符號了...
若你要取消這個換行符號,可利用 echo
的 -n option
:
$ echo -n
$
要想看看 echo
的 argument ,可試試如下的輸入:
$ echo hello
hello
$ echo -n hello
hello$
上兩個 echo
命令中,你會發現 argument 的部份顯示在你的熒幕,而換行符號則視 -n option
而定。
很明顯的,第二個 echo
由於換行符號被取消了,接下來的 shell prompt 就接在輸出結果同
一行了。
事實上, echo
除了 -n options
之外,常用選項還有:
-e :啟用反斜線控制字元的轉換
-E:關閉反斜線控制字元的轉換
-n :取消行末之換行符號
關於 echo
命令所支持的反斜線控制字元如下表:
\a: ALERT / BELL (從系統喇叭送出鈴聲)
\b: BACKSPACE ,也就是向左刪除鍵
\c:取消行末之換行符號
\E: ESCAPE,跳脫鍵
\f: FORMFEED,換頁字元
\n: NEWLINE,換行字元
\r: RETURN,回車鍵
\t: TAB,表格跳位鍵
\v: VERTICAL TAB,垂直表格跳位鍵
\n: ASCII 八進位編碼(以 x 開首為十六進位)
\\:反斜線本身
(四) " "
和‘ ’
的區別?
經過前面兩章的學習,應該很清楚當你在 shell prompt 後面敲打鍵盤、直到按下 Enter 的時
候,你輸入的文字就是 command line 了,然後 shell 才會以行程的方式執行你所交給它的命令。
但是,在 command line 輸入的每一個文字,對 shell 來說,是有類別之分的!
簡單而言, command line 的每一個 charactor ,分為如下兩種:
- literal:也就是普通純文字,對 shell 來說沒特殊功能。
- meta:對 shell 來說,具有特定功能的特殊保留字元。
Literal 沒甚麼好談的,凡舉 abcd、 123456 這些"文字"都是 literal ,但 meta 卻常使我們困惑。
事實上,前兩章我們在 command line 中已碰到兩個機乎每次都會碰到的 meta :
- IFS:由
<space>
或<tab>
或<enter>
三者之一組成(我們常用 space )。 - CR:由
<enter>
產生。
IFS 是用來拆解 command line 的每一個詞(word)用的,因為 shell command line 是按詞來處理的。
而 CR 則是用來結束 command line 用的,這也是為何我們敲
= : 設定變數。
$ : 作變數或運算替換(請不要與 shell prompt 搞混了)。
> :重導向 stdout。
< :重導向 stdin。
| :命令管線。
& :重導向 file descriptor ,或將命令置於背境執行。
( ) :將其內的命令置於 nested subshell 執行,或用於運算或命令替換。
{ } :將其內的命令置於 non-named function 中執行,或用在變數替換的界定範圍。
; :在前一個命令結束時,而忽略其返回值,繼續執行下一個命令。
&& :在前一個命令結束時,若返回值為 true,繼續執行下一個命令。
|| :在前一個命令結束時,若返回值為 false,繼續執行下一個命令。
! :執行 history 列表中的命令
假如我們需要在 command line 中將這些保留字元的功能關閉的話,就需要 quoting 處理了。在 bash 中,常用的 quoting 有如下三種方法:
- hard quote:
' '
(單引號),凡在 hard quote 中的所有 meta 均被關閉。 - soft quote:
" "
(雙引號),在 soft quoe 中大部份 meta 都會被關閉,但某些則保留(如$ )。 - escape : \ (反斜線),只有緊接在 escape (跳脫字元)之後的單一 meta 才被關閉。
下麵的例子將有助於我們對 quoting 的瞭解:
$ A=B C # 空格鍵未被關掉,作為 IFS 處理。
$ C: command not found.
$ echo $A
$
$ A="B C" # 空格鍵已被關掉,僅作為空格鍵處理。
$ echo $A
B C
在第一次設定 A 變數時,由於空格鍵沒被關閉, command line 將被解讀為:
- A=B 然後碰到
<IFS>
,再執行 C 命令。在第二次設定 A 變數時,由於空格鍵被置於 soft quote 中,因此被關閉,不再作為 IFS : - A=B
<space>
C
空格鍵無論在 soft quote 還是在 hard quote 中,均會被關閉。 Enter 鍵亦然。