linux : bash命令

一,什麼是Shell? 

shell是你(用戶)和Linux(或者更準確的說,是你和Linux內核)之間的接口程序。你在提示符下輸入的 
每個命令都由shell先解釋然後傳給Linux內核。 

shell 是一個命令語言解釋器(command-languageinterpreter)。擁有自己內建的shell命令集。此外, 
shell也能被系統中其他有效的Linux 實用程序和應用程序(utilitIEs andapplicationprograms)所調用。 

不論何時你鍵入一個命令,它都被Linux shell所解釋。一些命令,比如打印當前工作目錄命令(pwd), 
是包含在Linux bash內部的(就象Dos的內部命令)。其他命令,比如拷貝命令(cp)和移動命令(rm),是存在於 
文件系統中某個目錄下的單獨的程序。而對用戶來說,你不知道(或者可能不關心)一個命令是建立在shell內部還 
是一個單獨的程序。 


二,shell 是如何執行命令解釋的? 

shell 首先檢查命令是否是內部命令,不是的話再檢查是否是一個應用程序,這裏的應用程序可以是Linux 
本身的實用程序,比如ls 和 rm,也可以是購買的商業程序,比如xv,或者是公用軟件(public domain software), 
就象Ghostview。然後shell試着在搜索路徑裏尋找這些 應用程序。搜索路徑是一個能找到可執行程序的目錄列表。 
如果你鍵入的命令 不是一個內部命令並且在路徑裏沒有找到這個可執行文件,將會顯示一條錯誤 信息。而如果命令 
被成功的找到的話,shell的內部命令或應用程序將被分解爲 系統調用並傳給Linux內核。 

shell的另一個重要特性是它自身就是一個解釋型的程序設計語言,shell程序設計語言支持在高級語言裏所 
能見到的絕大多數程序控制結構,比如循環,函數,變量和數組。shell 編程語言很易學,並且一旦掌握後它將成爲 
你的得力工具。任何在提示符下能鍵入的命令也能放到一個可執行的shell程序裏,這意味着用shell語言能簡單地重 
復執行某一任務。 

三,shell 如何啓動 

shell在你成功地登錄進入系統後啓動,並始終作爲你與系統內核的交互手段直至你退出系統。你係統上的 
每位用戶都有一個缺省的shell。每個用戶的缺省shell在系統裏的passwd文件裏被指定,該文件的路徑是/etc/passwd。 
passwd文件裏還包含有其他東西:每個人的用戶ID號,一個口令加密後的拷貝和用戶登錄後立即執行的程序,(注: 
爲了加強安全性,現在的系統一般都把加密的口令放在另一個文件--shadow中,而passwd中存放口令的部分以一個x字 
符代替)雖然沒有嚴格規定這個程序必須是某個Linux shell,但大多數情況下都如此。 

四,最常用的shell 

在Linux 和 Unix系統裏可以使用多種不同的shell可以使用。最常用的幾種是Bourne shell (sh), C shell 
(csh), 和 Korn shell (ksh)。三種shell 都有它們的優點和缺點。 

1,Bourne shell 的作者是 Steven Bourne。它是 UNIX最初使用的shell並且在每種UNIX上都可以使用。
Bourne shell 在 shell編程方面相當優秀,但在處理與用戶的交互方面作得不如其他幾種 shell。 

2,C shell 由 BillJoy所寫,它更多的考慮了用戶界面的友好性。它支持象命令補齊(command-line 
completion)等一些 Bourne shell 所不支持的特性。普遍認爲C shell 的編程接口做的不如 Bourne shell, 但 
C shell 被很多C程序員使用因爲C shell的語法和C語言的很相似,這也是Cshell名稱的由來。 

3,Korn shell (ksh) 由 Dave Korn 所寫。它集合了C shell 和 Bourne shell的優點並且和 Bourne 
shell 完全兼容。 

除了這些 shell 以外,許多其他的 shell 程序吸收了這些原來的 shell程序的優點而成爲新的 shell 。 
在 Linux 上常見的有 tcsh (csh 的擴展),Bourne Again shell(bash, sh 的 擴展),和Public Domain Korn 
shell (pdksh, ksh 的擴展)。 

bash 是大多數Linux 系統的缺省 shell。Bourne Again shell (bash), 正如它的名字所暗示的,是 
Bourne shell 的擴展。bash 與Bourne shell 完全向後兼容,並且在 Bourne shell 的基礎上增加和增強了很多 
特性。bash 也包含了很多 C 和 Korn shell 裏的優點。bash 有很靈活和強大的編程接口,同時又有很友好的用戶 
界面。 

五, 缺省 shell--bash 

爲什麼要用 bash 來代替 sh 呢?Bourne shell最大的缺點在於它處理用戶的輸入方面。在 Bourne 
shell裏鍵入命令會很麻煩,尤其當你鍵入很多相似的命令時。而bash準備了幾種特性使命令的輸入變得更容易。 


1,命令補齊(Command-Line Completion) 

通常你在 bash (或任何其他的shell)下輸入命令時你不必把命令輸全shell就能判斷出你所要輸入的命
令。例如,假定當前的工作目錄包含以下的文件和子目錄: 

News/ bin/ games/ mail/ samplefile/ test/ 

如果你要進入 test 子目錄,你將會輸入以下的命令: 

cd test 

這個命令能夠滿足你的需要,但bash還提供了稍微不同的方法來完成同樣的事。因爲 test 是當前目錄裏 
唯一以字母t開頭的子目錄,bash在你只輸入字母 t後就能判斷出你要做什麼了: 

cd t 
在你鍵入那個字母后,唯一的可能就是 test 。想讓bash幫你結束命令的話,按下 Tab 鍵: 

cd t 

當你這樣做以後,bash將幫你補齊命令並顯示在屏幕上。但在你按下回車鍵以前命令並沒有被執行,bash 
會讓你檢驗補齊的命令是否是你真正需要的。在輸入象這樣短的命令時你也許看不出它的價值所在,甚至在命令很 
短時還會簡慢輸入的速度,但是當你要輸入的命令有點長時,你會發現這個特性是多麼的美好。 但是當目錄裏有不 
止一個以字母 t開頭的文件時會發生什麼情況呢?在你使用命令補齊時會有問題,讓我們看看下面的情況,當前目 
錄裏有下列內容: 

News/ bin/ mail/ samplefile test/ tools/ working/ 

現在這個目錄裏有兩個以字母 t 開頭的文件。假設你仍然想進入test子目錄,如何使用命令補齊呢?如果 
你象先前那樣鍵入: 

cd t 

bash將不知道你到底想進入哪個子目錄,因爲給出的信息並不唯一。如果你這樣做了的話,bash 將發出一 
聲蜂鳴 提醒你沒有足夠的信息來補齊你的命令。蜂鳴之後bash並不改變輸入的命令,這將使你能在原來的基礎上再 
輸入更多的信息,在這個例子中你僅需再鍵入一個 e 並再按一下 Tab 鍵,這時 bash就有足夠的信息來完成你的命 
令了: 

cd test 

當你輸入命令時不論何時按下 Tab 鍵,bash都將盡其所能地試圖補齊命令,不行的話會發出蜂鳴來提醒你 
需要更多的信息。你需要鍵入更多的字符,並再次按下 Tab鍵,重複這個過程直至你期望的命令出現。 



2,通配符 

另一個使命令輸入變得更簡單的方法是在命令中使用通配符。bash支持三種通配符: 

* 匹配任何字符和任何數目的字符 

? 匹配任何單字符 

[...] 匹配任何包含在括號裏的單字符 

* 通配符的使用有些象命令補齊。例如,假設當前目錄包含以下文件: 

News/ bin/ games/ mail/ samplefile/ test/ 

如果你想進入 test 目錄,你將鍵入 cd test, 或者你想用命令補齊: 

cd t 

現在有第三種方法來做同樣的事。因爲僅有一個文件以字母 t 開頭,你也能用 *通配符來進入該目錄。鍵 
入下列命令: 

cd t* 

* 匹配任何字符和任何數目的字符,所以 shell 將把 t* 替換爲test(當前目錄裏唯一和通配方案匹配的 
文件)。 當前目錄裏只有一個文件以字母 t開頭的話這將是可靠的。但是如果當前目錄裏有不止一個文件以字母 t 
開頭, shell將試着進入第一個符合匹配方案的目錄,這個目錄是以字母表排序的第一個目錄,這個目錄也許是也許 
不是你所期望的。 

通配符 *的一個更實際的用途是通配你要執行的命令中的多個名字相似的文件。例如,假設當前目錄裏包含 
以下文件: 

ch1.doc ch2.doc ch3.doc chimp config mail/ test/ tools/ 

如果你需要打印所有擴展名是 .doc 的文件,你能使用象這樣簡化的命令: 

lpr *.doc 

在這個例子中,bash 將把 *.doc替換爲當前目錄下所有文件名符合通配方案的文件。在 bash 進行了替換 
後,該命令將被處理爲: 

lpr ch1.doc ch2.doc ch3.doc 

lpr 命令將以ch1.doc, ch2.doc, 和 ch3.doc爲參數被調用。 


通配符 ? 除了只能匹配單個字符外,其他功能都與通配符 *相同,如果用通配符? 來打印前面提到的那個 
目錄裏所 有擴展名是 .doc的文件的話,鍵入下面的命令: 

lpr ch?.doc 

通配符[...]能匹配括號中給出的字符或字符範圍。同樣以前面的目錄爲例,打印那個目錄裏所有擴展名是 
.doc 的文件,你可以鍵入下列命令之一: 

lpr ch[123].doc 

或者: 

lpr ch[1-3].doc 

3,命令歷史記錄 

bash 也支持命令歷史記錄。這意味着 bash保留了一定數目的你先前已經在shell裏輸入過的命令。這個數 
目取決於一個叫做HISTSIZE的變量。 bash 把你先前輸入的命令文本保存在一個歷史列表中。當你用你的帳號登錄後 
歷史列表將根據一個歷史文件被初始化。歷史文件的文件名被一個叫 HISTFILE的 bash變量指定。歷史文件的缺省名 
字是 .bash_history。這個文件通常在你的用戶目錄中。(注意該文件的文件名以一個句號開頭,這意味着它是隱含 
的,僅當你帶 -a 或 -A參數的 ls 命令列目錄時纔可見) 

僅將先前的命令存在歷史文件裏是沒有用的,所以 bash提供了幾種方法來調用它們。使用歷史記錄列表最 
簡單的方法是用上方向鍵。按下上方向鍵後最後鍵入的命令將出現在命令行上。再按一下則倒數第二條命令會出現, 
以此類推。 如果上翻多了的話也可以用向下的方向鍵來下翻。(和 DOS實用程序doskey一樣)如果需要的話,顯示 
在命令行上的 歷史命令可以被編輯。 

另一個使用命令歷史文件的方法是用 bash 的內部命令 history 和 fc(fix命令)命令來顯示和編輯歷史命 
令。 history命令能以兩種不同的方法來調用。 

第一種是: 

history [n] 

當 history 命令沒有參數時,整個歷史命令列表的內容將被顯示出來。下面是一個命令歷史列表的例子: 

1 mkdir /usr/games/pool 

2 cp XpoolTable-1.2.linux.tar.z /usr/games/pool 

3 cd /usr/games/pool/ 

4 ls 

5 gunzip XpoolTable-1.2.linux.tar.z 

6 tar -xf XpoolTable-1.2.linux.tar 

7 ls 

8 cd Xpool 

9 ls 

10 xinit 

11 exit 

12 which zip 

13 zip 

14 more readme 

15 vi readme 

16 exit 

使用 n 參數的作用是僅有最後 n 個歷史命令會被列出。例如,history 5顯示最後 5個命令。 

調用 history命令的第二種方法用於修改命令歷史列表文件的內容。命令的語法如下: 

history [-r|w|a|n] [filename] 

這種形式中,-r 選項告訴 history命令讀命令歷史列表文件的內容並且把它們當作當前的命令歷史列表。 
-w 選項將把當前的命令歷史記錄寫入文件中並覆蓋文件原來的內容。 
-a選項把當前的命令歷史記錄追加到文件中。 
-n 選項將讀取文件中的內容並加入到當前歷史命令列表中。如果 filename選項沒有被指定,history 命令將用變 
量 HISTFILE 的值來代替。 

fc 命令能用兩種方法來編輯歷史命令。 

第一種使用下列語法: 

fc [-e editor_name] [-n] [-l] [-r] [first] [last] 

這裏所有參數都是可選的。 
-e editor_name選項用來指定用於編輯命令的文本編輯器。 
first 和 last 選項用於選擇列出歷史命令的範圍,既可以是數字也可以是字符串。 
-n選項禁止列出命令的編號。 
-r 選項反向列出匹配的命令。 
-l選項把匹配的命令行列在屏幕上(而不是在編輯器中)。 
如果-e editor_name參數沒有被指定,則以變量FCEDIT的值來代替,如果該變量不存在的話,則用變量EDITOR的值 
來代替,都不存在的話將使用vi編輯器。 

3,別名 

bash的另一個使你的工作變得輕鬆的方法是命令別名。命令別名通常是其他命令的縮寫,用來減少鍵盤輸 
入。例如,你經常要鍵入如下的命令,你也許會傾向於爲它建立一個別名來減少工作量: 

cd /usr/X11/lib/X11/fvwm/sample-configs 

假如爲這個長命令建立一個名爲goconfig的別名,在bash提示符下鍵入如下命令: 

alias goconfig=cd /usr/X11/lib/X11/fvwm/sample-configs 

現在,除非你退出bash,鍵入goconfig將和原來的長命令有同樣的作用。如果想取消別名,可以使用下面的命令: 

unalias goconfig 

這是一些很多用戶認爲有用的別名,你可以把它們寫入你的.profile文件中提高工作效 : 

alias ll=ls -l 

alias log=logout 

alias ls=ls -F 

如果你是一名DOS用戶並且習慣了DOS命令,你能下面的別名定義使你的 Linux表現得象DOS 一樣: 

alias dir=ls 

alias copy=cp 

alias rename=mv 

alias md=mkdir 

alias rd=rmdir 



注意: 在定義別名時,等號的兩頭不能有空格,否則 shell 不能決定你需要做什麼。僅在你的命令中包含有空格 
或特殊字符時才需要引號。 


如果你鍵入不帶任何參數的alias命令,將顯示所有已定義的別名,例如: 

alias dir=ls 

alias ll=ls -l 

alias ls=ls -F 

alias md=mkdir 

alias net=term < /dev/modem > /dev/modem 2> /dev/null& 

alias rd=rmdir 

4,輸入重定向 

輸入重定向用於改變一個命令的輸入源。一些命令需要在命令行裏輸入足夠的信息才能工作。比如 rm,你 
必須在命令行裏告訴 rm它你要刪除的文件。另一些命令則需要更詳細的輸入,這些命令的輸入可能是一個文件。比 
如命令 wc統計輸入給它的文件裏的文件裏的字符數,單詞數和行數。如果你僅在命令行上鍵 入 wc,wc 將等待你告 
訴它要統計什麼,這時 bash就好象死了一樣,你鍵入的每樣東西都出現在屏幕上,但什麼事也不會發生。這是因爲 
wc 命令正在爲自己收集輸入。如果你按下Ctrl-D,wc 命令的結果將被寫在屏幕上。如果你輸入一個文件名做參數, 
象下面的例子一樣,wc將返回文件所包含的字符數,單詞數,和行數: 

wc test 

11 2 1 

另一種把test文件內容傳給wc命令的方法是重定向wc的輸入。 

<符號在bash裏用於把當前命令的輸入重定向爲指定的文件。所以可以用下面的命令來把wc 
命令的輸入重定向爲 test 文件: 

wc < test 

11 2 1 


輸入重定向並不經常使用因爲大多數命令都以參數的形式在命令行上指定輸入文件的文件名。儘管如此, 
當你使用一個不接受文件名爲輸入參數的命令,而需要的輸入又是在一個已存在的文件裏時,你就能用輸入重定向 
解決問題。 

5,輸出重定向 

輸出重定向比輸入重定向更常用。輸出重定向使你能把一個命令的輸出重定向到一個文件裏,而不是顯示在 
屏幕上。 

很多情況下都可以使用這種功能。例如,如果某個命令的輸出很多,在屏幕上不能完全顯示,你能把它重定 
向到一個文件中,稍後再用文本編輯器來打開這個文件;當你想保存一個命令的輸出時也可以使用這種方法。還有, 
輸出重定向可以用於把一個命令的輸出當作另一個命令的輸入時。(還有一種更簡單的方法可以把一個命令的輸出當 
作另一個命令的輸入,就是使用管道) 

輸出重定向的使用與輸入重定向很相似,但是輸出重定向的符號是 > 。 

注意:記憶輸入/輸出重定向符號的最好方法是把<看作是一個漏斗,漏斗的小口指向需要輸入的命令(因 
爲需要接受輸入的命令會在 <的左手邊),而把>當作一個大口指向有輸出的命令的漏斗。 

重定向舉例,當你要把 ls 命令的輸出保存爲一個名爲 Directory.out的文件時,你可以使用下面的命令: 

ls > directory.out 

6,管道 


管道可以把一系列命令連接起來。這意味着第一個命令的輸出會通過管道傳給第二個命令而作爲第二個命令 
的輸入,第二個命令的輸出又會作爲第三個命令的輸入,以此類推。而管道行中最後一個命令的輸出纔會顯示在屏幕 
上(如果命令行裏使用了輸出重定向的話,將會放進一個文件裏)。 你能通過使用管道符 |來建立一個管道行,下 
面的示例就是一個管道行: 

cat sample.text | grep "High" | wc -l 

這個管道將把 cat 命令(列出一個文件的內容)的輸出送給grep命令。grep命令在輸入裏查找單詞 High, 
grep命令的輸出則是所有包含單詞High的行,這個輸出又被送給 wc命令。帶 -l選項的 wc命令將統計輸入裏的行數。 
假設sample.txt的內容如下: 

Things to do today: 

Low: Go grocery shopping 

High: Return movie 

High: Clear level 3 in Alien vs. Predator 

Medium: Pick up clothes from dry cleaner 


管道行將返回結果 2,指出你今天有兩件很重要的事要做: 

cat sample.text | grep "High" | wc -l 



7,提示符 

bash 有兩級用戶提示符。第一級是你經常看到的 bash在等待命令輸入時的提示符。缺省的一級提示符是字 
符$(如果是超級用戶,則是#號)。你可以通過改變bash的PS1變量的值來改變你的缺省提示符,例如: 

PS1="Please enter a command" 

把bash shell 的提示符該爲指定的字符串。 
當bash期待輸入更多的信息以完成命令時顯示第二級提示符。缺省的第二級提示符是 >。果你要改變第二級 
提示符, 可以通過設置PS2變量的值來實現: 

PS2="I need more information" 

另外你還可以用特殊的字符來定義你的提示符,下面的列表列出了最常用的特殊字符。 
提示符特殊字符代碼字符含義: 

! 顯示該命令的歷史記錄編號。 

# 顯示當前命令的命令編號。 

$ 顯示$符作爲提示符,如果用戶是root的話,則顯示#號。 

顯示反斜槓。 

d 顯示當前日期。 

h 顯示主機名。 

n 打印新行。 

nnn 顯示nnn的八進制值。 

s 顯示當前運行的shell的名字。 

t 顯示當前時間。 

u 顯示當前用戶的用戶名。 

W 顯示當前工作目錄的名字。 

w 顯示當前工作目錄的路徑。 


這些特殊字符能組合成很多種有用的提示符方案(也可以組合爲很奇異的方案),例如把 PS1 設爲:

PS1="t" 

這導致提示符顯示當前的時間,就象下面的顯示一樣(提示符後面將不會有空格): 

02:16:15 


而下面的設置: 

PS1=t 

將導致提示符變成下面的樣子: 



這顯示了設置中引號的重要性,下面的提示符串: 

PS1="t " 

會使提示符看起來象這個樣子: 

02:16:30 

這種情況下,提示符後面會有一個空格,因爲引號裏有一個空格。 

8,作業控制(Job Control) 


作業控制能夠控制當前正在運行的進程的行爲。特別地,你能把一個正在運行的進程掛起,稍後再恢復它的 
運行。bash保持對所有已啓動的進程的跟蹤,你能在一個正在運行的進程的生命期內的任何時候把它掛起或是使它恢 
復運行。 

按下 Ctrl-Z 使一個運行的進程掛起。bg命令使一個被掛起的進程在後臺恢復運行,反之 fg 命令使進程在 
前臺恢復運行。這幾個命令在當用戶想在後臺運行而意外的把它放到了前臺時,經常被用到。當一個命令在前臺被運 
行時, 它會禁止用戶與 shell的交互,直到該命令結束。這通常不會造成麻煩,因爲大多數命令很快就執行完了。 
如果你要運行的命令要花費很長的時間的話,我們通常會把它放到後臺,以使我們能在前臺繼續輸入其他命令。 

例如,你輸入 這個命令: 

command find / -name "test" > find.out 

它將尋找整個文件系統中的名爲test的文件並把結果保存在一個叫fing.out的文件裏。如果在前臺運行的 
話,根據文件系統的大小,你的shell將有數秒甚至數分鐘不能使用,你不想這樣的話可以再輸入以下面的內容: 

control-z 

bg 

find 命令首先被掛起,再在後臺繼續被執行,並且你能馬上回到bash下。 

六,用戶化配置bash 


本文已經描述了許多用戶化配置bash的方法。但知道現在爲止,我們所做的改動都僅在當前運行的bash下才 
有效。一旦退出系統,所有的改動也隨之消失了。爲了保存這些用戶化配置,你必須把它們保存到一個bash的初始化 
文件裏。 

你能把任何想每次進入cash都執行的命令放到初始化文件裏。這個文件裏最常見到的命令通常是alias和變 
量的初始化。bash的初始化文件叫做 profile。每個使用bash的用戶都有一個.profile文件在他的用戶目錄裏。bash 
在每次啓動時都讀取這個文件,並執行所有包含的命令。 

下面的代碼是缺省的.profile文件的內容。這個文件的位置在/etc目錄。如果你想設置自己的bash 的話把 
它拷到你的用戶目錄裏(如果還沒有的話)並命名爲.profile。 

注意:有些setup程序會在建立用戶時自動放一個.profile文件的拷貝在你的用戶目錄裏。但是並不是所有 
的都這麼做,所以最好先檢查一下你的用戶目錄。記住所有以句點開頭的文件都是隱含的,只有用ls -a或ls -A命令 
才能列出。 


# commands common to all logins 

export OPENWINHOME=/usr/openwin 

export MINICOM="-c on" 

export MANPATH=/usr/local/man:/usr/man/preformat:/usr/man:/X11/man:/usr/openwin /m 
an 

export HOSTNAME="`cat /etc/HOSTNAME`" 

PATH="$PATH:/usr/X11/bin:$OPENWINHOME/bin:/usr/games:." 

LESS=-MM 

# I had problems using eval test instead of TERM=, but you might want to # try 
it anyway. I think with the right /etc/termcap it would work great. # eval tset 
-sQ "$TERM"if [ "$TERM" = "" -o "$TERM" = 
"unknown"]; then 

TERM=linux 

#PS1=hostname:pwd# ` 

if [ "$SHELL" = "/bin/pdksh" -o "$SHELL" = "/bin/ksh" ]; then 

PS1="! $" 

elif [ "$SHELL" = "/bin/zsh" ]; then 

PS1="%m:%~%# " 

elif [ "$SHELL" = "/bin/ash" ]; then 

PS1="$ " 

else 

PS1=h:w$ ` 

fi 

PS2=> ` 

ignoreeof=10 

export PATH DISPLAY LESS TERM PS1 PS2 ignoreeof 

umask 022 

# set up the color-ls environment variables: 

if [ "$SHELL" = "/bin/zsh" l; then 

eval dircolors -z 

elif [ "$SHELL" = "/bin/ash" l; then 

eval dircolors -s 

else 

eval dircolors -b 

fi 

echo 

fortune 

echo 

export TAPE="/dev/nftape" 


七,bash 命令概要 

這是幾個最有用的bash內部命令: 

alias: 設置bash別名。 

bg: 使一個被掛起的進程在後臺繼續執行。 

cd: 改變當前工作目錄。 

exit: 終止shell。 

export: 使變量的值對當前shell的所有子進程都可見 。 

fc: 用來編輯歷史命令列表裏的命令。 

fg: 使一個被掛起的進程在前臺繼續執行。 

help: 顯示bash內部命令的幫助信息。 

kill: 終止某個進程一,什麼是Shell? 

shell是你(用戶)和Linux(或者更準確的說,是你和Linux內核)之間的接口程序。你在提示符下輸入的 
每個命令都由shell先解釋然後傳給Linux內核。 

shell 是一個命令語言解釋器(command-languageinterpreter)。擁有自己內建的shell命令集。此外, 
shell也能被系統中其他有效的Linux 實用程序和應用程序(utilitIEs andapplicationprograms)所調用。 

不論何時你鍵入一個命令,它都被Linux shell所解釋。一些命令,比如打印當前工作目錄命令(pwd), 
是包含在Linux bash內部的(就象Dos的內部命令)。其他命令,比如拷貝命令(cp)和移動命令(rm),是存在於 
文件系統中某個目錄下的單獨的程序。而對用戶來說,你不知道(或者可能不關心)一個命令是建立在shell內部還 
是一個單獨的程序。 


二,shell 是如何執行命令解釋的? 

shell 首先檢查命令是否是內部命令,不是的話再檢查是否是一個應用程序,這裏的應用程序可以是Linux 
本身的實用程序,比如ls 和 rm,也可以是購買的商業程序,比如xv,或者是公用軟件(public domain software), 
就象Ghostview。然後shell試着在搜索路徑裏尋找這些 應用程序。搜索路徑是一個能找到可執行程序的目錄列表。 
如果你鍵入的命令 不是一個內部命令並且在路徑裏沒有找到這個可執行文件,將會顯示一條錯誤 信息。而如果命令 
被成功的找到的話,shell的內部命令或應用程序將被分解爲 系統調用並傳給Linux內核。 

shell的另一個重要特性是它自身就是一個解釋型的程序設計語言,shell程序設計語言支持在高級語言裏所 
能見到的絕大多數程序控制結構,比如循環,函數,變量和數組。shell 編程語言很易學,並且一旦掌握後它將成爲 
你的得力工具。任何在提示符下能鍵入的命令也能放到一個可執行的shell程序裏,這意味着用shell語言能簡單地重 
復執行某一任務。 

三,shell 如何啓動 

shell在你成功地登錄進入系統後啓動,並始終作爲你與系統內核的交互手段直至你退出系統。你係統上的 
每位用戶都有一個缺省的shell。每個用戶的缺省shell在系統裏的passwd文件裏被指定,該文件的路徑是/etc/passwd。 
passwd文件裏還包含有其他東西:每個人的用戶ID號,一個口令加密後的拷貝和用戶登錄後立即執行的程序,(注: 
爲了加強安全性,現在的系統一般都把加密的口令放在另一個文件--shadow中,而passwd中存放口令的部分以一個x字 
符代替)雖然沒有嚴格規定這個程序必須是某個Linux shell,但大多數情況下都如此。 

四,最常用的shell 

在Linux 和 Unix系統裏可以使用多種不同的shell可以使用。最常用的幾種是Bourne shell (sh), C shell 
(csh), 和 Korn shell (ksh)。三種shell 都有它們的優點和缺點。 

1,Bourne shell 的作者是 Steven Bourne。它是 UNIX最初使用的shell並且在每種UNIX上都可以使用。
Bourne shell 在 shell編程方面相當優秀,但在處理與用戶的交互方面作得不如其他幾種 shell。 

2,C shell 由 BillJoy所寫,它更多的考慮了用戶界面的友好性。它支持象命令補齊(command-line 
completion)等一些 Bourne shell 所不支持的特性。普遍認爲C shell 的編程接口做的不如 Bourne shell, 但 
C shell 被很多C程序員使用因爲C shell的語法和C語言的很相似,這也是Cshell名稱的由來。 

3,Korn shell (ksh) 由 Dave Korn 所寫。它集合了C shell 和 Bourne shell的優點並且和 Bourne 
shell 完全兼容。 

除了這些 shell 以外,許多其他的 shell 程序吸收了這些原來的 shell程序的優點而成爲新的 shell 。 
在 Linux 上常見的有 tcsh (csh 的擴展),Bourne Again shell(bash, sh 的 擴展),和Public Domain Korn 
shell (pdksh, ksh 的擴展)。 

bash 是大多數Linux 系統的缺省 shell。Bourne Again shell (bash), 正如它的名字所暗示的,是 
Bourne shell 的擴展。bash 與Bourne shell 完全向後兼容,並且在 Bourne shell 的基礎上增加和增強了很多 
特性。bash 也包含了很多 C 和 Korn shell 裏的優點。bash 有很靈活和強大的編程接口,同時又有很友好的用戶 
界面。 

五, 缺省 shell--bash 

爲什麼要用 bash 來代替 sh 呢?Bourne shell最大的缺點在於它處理用戶的輸入方面。在 Bourne 
shell裏鍵入命令會很麻煩,尤其當你鍵入很多相似的命令時。而bash準備了幾種特性使命令的輸入變得更容易。 


1,命令補齊(Command-Line Completion) 

通常你在 bash (或任何其他的shell)下輸入命令時你不必把命令輸全shell就能判斷出你所要輸入的命
令。例如,假定當前的工作目錄包含以下的文件和子目錄: 

News/ bin/ games/ mail/ samplefile/ test/ 

如果你要進入 test 子目錄,你將會輸入以下的命令: 

cd test 

這個命令能夠滿足你的需要,但bash還提供了稍微不同的方法來完成同樣的事。因爲 test 是當前目錄裏 
唯一以字母t開頭的子目錄,bash在你只輸入字母 t後就能判斷出你要做什麼了: 

cd t 
在你鍵入那個字母后,唯一的可能就是 test 。想讓bash幫你結束命令的話,按下 Tab 鍵: 

cd t 

當你這樣做以後,bash將幫你補齊命令並顯示在屏幕上。但在你按下回車鍵以前命令並沒有被執行,bash 
會讓你檢驗補齊的命令是否是你真正需要的。在輸入象這樣短的命令時你也許看不出它的價值所在,甚至在命令很 
短時還會簡慢輸入的速度,但是當你要輸入的命令有點長時,你會發現這個特性是多麼的美好。 但是當目錄裏有不 
止一個以字母 t開頭的文件時會發生什麼情況呢?在你使用命令補齊時會有問題,讓我們看看下面的情況,當前目 
錄裏有下列內容: 

News/ bin/ mail/ samplefile test/ tools/ working/ 

現在這個目錄裏有兩個以字母 t 開頭的文件。假設你仍然想進入test子目錄,如何使用命令補齊呢?如果 
你象先前那樣鍵入: 

cd t 

bash將不知道你到底想進入哪個子目錄,因爲給出的信息並不唯一。如果你這樣做了的話,bash 將發出一 
聲蜂鳴 提醒你沒有足夠的信息來補齊你的命令。蜂鳴之後bash並不改變輸入的命令,這將使你能在原來的基礎上再 
輸入更多的信息,在這個例子中你僅需再鍵入一個 e 並再按一下 Tab 鍵,這時 bash就有足夠的信息來完成你的命 
令了: 

cd test 

當你輸入命令時不論何時按下 Tab 鍵,bash都將盡其所能地試圖補齊命令,不行的話會發出蜂鳴來提醒你 
需要更多的信息。你需要鍵入更多的字符,並再次按下 Tab鍵,重複這個過程直至你期望的命令出現。 



2,通配符 

另一個使命令輸入變得更簡單的方法是在命令中使用通配符。bash支持三種通配符: 

* 匹配任何字符和任何數目的字符 

? 匹配任何單字符 

[...] 匹配任何包含在括號裏的單字符 

* 通配符的使用有些象命令補齊。例如,假設當前目錄包含以下文件: 

News/ bin/ games/ mail/ samplefile/ test/ 

如果你想進入 test 目錄,你將鍵入 cd test, 或者你想用命令補齊: 

cd t 

現在有第三種方法來做同樣的事。因爲僅有一個文件以字母 t 開頭,你也能用 *通配符來進入該目錄。鍵 
入下列命令: 

cd t* 

* 匹配任何字符和任何數目的字符,所以 shell 將把 t* 替換爲test(當前目錄裏唯一和通配方案匹配的 
文件)。 當前目錄裏只有一個文件以字母 t開頭的話這將是可靠的。但是如果當前目錄裏有不止一個文件以字母 t 
開頭, shell將試着進入第一個符合匹配方案的目錄,這個目錄是以字母表排序的第一個目錄,這個目錄也許是也許 
不是你所期望的。 

通配符 *的一個更實際的用途是通配你要執行的命令中的多個名字相似的文件。例如,假設當前目錄裏包含 
以下文件: 

ch1.doc ch2.doc ch3.doc chimp config mail/ test/ tools/ 

如果你需要打印所有擴展名是 .doc 的文件,你能使用象這樣簡化的命令: 

lpr *.doc 

在這個例子中,bash 將把 *.doc替換爲當前目錄下所有文件名符合通配方案的文件。在 bash 進行了替換 
後,該命令將被處理爲: 

lpr ch1.doc ch2.doc ch3.doc 

lpr 命令將以ch1.doc, ch2.doc, 和 ch3.doc爲參數被調用。 


通配符 ? 除了只能匹配單個字符外,其他功能都與通配符 *相同,如果用通配符? 來打印前面提到的那個 
目錄裏所 有擴展名是 .doc的文件的話,鍵入下面的命令: 

lpr ch?.doc 

通配符[...]能匹配括號中給出的字符或字符範圍。同樣以前面的目錄爲例,打印那個目錄裏所有擴展名是 
.doc 的文件,你可以鍵入下列命令之一: 

lpr ch[123].doc 

或者: 

lpr ch[1-3].doc 

3,命令歷史記錄 

bash 也支持命令歷史記錄。這意味着 bash保留了一定數目的你先前已經在shell裏輸入過的命令。這個數 
目取決於一個叫做HISTSIZE的變量。 bash 把你先前輸入的命令文本保存在一個歷史列表中。當你用你的帳號登錄後 
歷史列表將根據一個歷史文件被初始化。歷史文件的文件名被一個叫 HISTFILE的 bash變量指定。歷史文件的缺省名 
字是 .bash_history。這個文件通常在你的用戶目錄中。(注意該文件的文件名以一個句號開頭,這意味着它是隱含 
的,僅當你帶 -a 或 -A參數的 ls 命令列目錄時纔可見) 

僅將先前的命令存在歷史文件裏是沒有用的,所以 bash提供了幾種方法來調用它們。使用歷史記錄列表最 
簡單的方法是用上方向鍵。按下上方向鍵後最後鍵入的命令將出現在命令行上。再按一下則倒數第二條命令會出現, 
以此類推。 如果上翻多了的話也可以用向下的方向鍵來下翻。(和 DOS實用程序doskey一樣)如果需要的話,顯示 
在命令行上的 歷史命令可以被編輯。 

另一個使用命令歷史文件的方法是用 bash 的內部命令 history 和 fc(fix命令)命令來顯示和編輯歷史命 
令。 history命令能以兩種不同的方法來調用。 

第一種是: 

history [n] 

當 history 命令沒有參數時,整個歷史命令列表的內容將被顯示出來。下面是一個命令歷史列表的例子: 

1 mkdir /usr/games/pool 

2 cp XpoolTable-1.2.linux.tar.z /usr/games/pool 

3 cd /usr/games/pool/ 

4 ls 

5 gunzip XpoolTable-1.2.linux.tar.z 

6 tar -xf XpoolTable-1.2.linux.tar 

7 ls 

8 cd Xpool 

9 ls 

10 xinit 

11 exit 

12 which zip 

13 zip 

14 more readme 

15 vi readme 

16 exit 

使用 n 參數的作用是僅有最後 n 個歷史命令會被列出。例如,history 5顯示最後 5個命令。 

調用 history命令的第二種方法用於修改命令歷史列表文件的內容。命令的語法如下: 

history [-r|w|a|n] [filename] 

這種形式中,-r 選項告訴 history命令讀命令歷史列表文件的內容並且把它們當作當前的命令歷史列表。 
-w 選項將把當前的命令歷史記錄寫入文件中並覆蓋文件原來的內容。 
-a選項把當前的命令歷史記錄追加到文件中。 
-n 選項將讀取文件中的內容並加入到當前歷史命令列表中。如果 filename選項沒有被指定,history 命令將用變 
量 HISTFILE 的值來代替。 

fc 命令能用兩種方法來編輯歷史命令。 

第一種使用下列語法: 

fc [-e editor_name] [-n] [-l] [-r] [first] [last] 

這裏所有參數都是可選的。 
-e editor_name選項用來指定用於編輯命令的文本編輯器。 
first 和 last 選項用於選擇列出歷史命令的範圍,既可以是數字也可以是字符串。 
-n選項禁止列出命令的編號。 
-r 選項反向列出匹配的命令。 
-l選項把匹配的命令行列在屏幕上(而不是在編輯器中)。 
如果-e editor_name參數沒有被指定,則以變量FCEDIT的值來代替,如果該變量不存在的話,則用變量EDITOR的值 
來代替,都不存在的話將使用vi編輯器。 

3,別名 

bash的另一個使你的工作變得輕鬆的方法是命令別名。命令別名通常是其他命令的縮寫,用來減少鍵盤輸 
入。例如,你經常要鍵入如下的命令,你也許會傾向於爲它建立一個別名來減少工作量: 

cd /usr/X11/lib/X11/fvwm/sample-configs 

假如爲這個長命令建立一個名爲goconfig的別名,在bash提示符下鍵入如下命令: 

alias goconfig=cd /usr/X11/lib/X11/fvwm/sample-configs 

現在,除非你退出bash,鍵入goconfig將和原來的長命令有同樣的作用。如果想取消別名,可以使用下面的命令: 

unalias goconfig 

這是一些很多用戶認爲有用的別名,你可以把它們寫入你的.profile文件中提高工作效 : 

alias ll=ls -l 

alias log=logout 

alias ls=ls -F 

如果你是一名DOS用戶並且習慣了DOS命令,你能下面的別名定義使你的 Linux表現得象DOS 一樣: 

alias dir=ls 

alias copy=cp 

alias rename=mv 

alias md=mkdir 

alias rd=rmdir 



注意: 在定義別名時,等號的兩頭不能有空格,否則 shell 不能決定你需要做什麼。僅在你的命令中包含有空格 
或特殊字符時才需要引號。 


如果你鍵入不帶任何參數的alias命令,將顯示所有已定義的別名,例如: 

alias dir=ls 

alias ll=ls -l 

alias ls=ls -F 

alias md=mkdir 

alias net=term < /dev/modem > /dev/modem 2> /dev/null& 

alias rd=rmdir 

4,輸入重定向 

輸入重定向用於改變一個命令的輸入源。一些命令需要在命令行裏輸入足夠的信息才能工作。比如 rm,你 
必須在命令行裏告訴 rm它你要刪除的文件。另一些命令則需要更詳細的輸入,這些命令的輸入可能是一個文件。比 
如命令 wc統計輸入給它的文件裏的文件裏的字符數,單詞數和行數。如果你僅在命令行上鍵 入 wc,wc 將等待你告 
訴它要統計什麼,這時 bash就好象死了一樣,你鍵入的每樣東西都出現在屏幕上,但什麼事也不會發生。這是因爲 
wc 命令正在爲自己收集輸入。如果你按下Ctrl-D,wc 命令的結果將被寫在屏幕上。如果你輸入一個文件名做參數, 
象下面的例子一樣,wc將返回文件所包含的字符數,單詞數,和行數: 

wc test 

11 2 1 

另一種把test文件內容傳給wc命令的方法是重定向wc的輸入。 

<符號在bash裏用於把當前命令的輸入重定向爲指定的文件。所以可以用下面的命令來把wc 
命令的輸入重定向爲 test 文件: 

wc < test 

11 2 1 


輸入重定向並不經常使用因爲大多數命令都以參數的形式在命令行上指定輸入文件的文件名。儘管如此, 
當你使用一個不接受文件名爲輸入參數的命令,而需要的輸入又是在一個已存在的文件裏時,你就能用輸入重定向 
解決問題。 

5,輸出重定向 

輸出重定向比輸入重定向更常用。輸出重定向使你能把一個命令的輸出重定向到一個文件裏,而不是顯示在 
屏幕上。 

很多情況下都可以使用這種功能。例如,如果某個命令的輸出很多,在屏幕上不能完全顯示,你能把它重定 
向到一個文件中,稍後再用文本編輯器來打開這個文件;當你想保存一個命令的輸出時也可以使用這種方法。還有, 
輸出重定向可以用於把一個命令的輸出當作另一個命令的輸入時。(還有一種更簡單的方法可以把一個命令的輸出當 
作另一個命令的輸入,就是使用管道) 

輸出重定向的使用與輸入重定向很相似,但是輸出重定向的符號是 > 。 

注意:記憶輸入/輸出重定向符號的最好方法是把<看作是一個漏斗,漏斗的小口指向需要輸入的命令(因 
爲需要接受輸入的命令會在 <的左手邊),而把>當作一個大口指向有輸出的命令的漏斗。 

重定向舉例,當你要把 ls 命令的輸出保存爲一個名爲 Directory.out的文件時,你可以使用下面的命令: 

ls > directory.out 

6,管道 


管道可以把一系列命令連接起來。這意味着第一個命令的輸出會通過管道傳給第二個命令而作爲第二個命令 
的輸入,第二個命令的輸出又會作爲第三個命令的輸入,以此類推。而管道行中最後一個命令的輸出纔會顯示在屏幕 
上(如果命令行裏使用了輸出重定向的話,將會放進一個文件裏)。 你能通過使用管道符 |來建立一個管道行,下 
面的示例就是一個管道行: 

cat sample.text | grep "High" | wc -l 

這個管道將把 cat 命令(列出一個文件的內容)的輸出送給grep命令。grep命令在輸入裏查找單詞 High, 
grep命令的輸出則是所有包含單詞High的行,這個輸出又被送給 wc命令。帶 -l選項的 wc命令將統計輸入裏的行數。 
假設sample.txt的內容如下: 

Things to do today: 

Low: Go grocery shopping 

High: Return movie 

High: Clear level 3 in Alien vs. Predator 

Medium: Pick up clothes from dry cleaner 


管道行將返回結果 2,指出你今天有兩件很重要的事要做: 

cat sample.text | grep "High" | wc -l 



7,提示符 

bash 有兩級用戶提示符。第一級是你經常看到的 bash在等待命令輸入時的提示符。缺省的一級提示符是字 
符$(如果是超級用戶,則是#號)。你可以通過改變bash的PS1變量的值來改變你的缺省提示符,例如: 

PS1="Please enter a command" 

把bash shell 的提示符該爲指定的字符串。 
當bash期待輸入更多的信息以完成命令時顯示第二級提示符。缺省的第二級提示符是 >。果你要改變第二級 
提示符, 可以通過設置PS2變量的值來實現: 

PS2="I need more information" 

另外你還可以用特殊的字符來定義你的提示符,下面的列表列出了最常用的特殊字符。 
提示符特殊字符代碼字符含義: 

! 顯示該命令的歷史記錄編號。 

# 顯示當前命令的命令編號。 

$ 顯示$符作爲提示符,如果用戶是root的話,則顯示#號。 

顯示反斜槓。 

d 顯示當前日期。 

h 顯示主機名。 

n 打印新行。 

nnn 顯示nnn的八進制值。 

s 顯示當前運行的shell的名字。 

t 顯示當前時間。 

u 顯示當前用戶的用戶名。 

W 顯示當前工作目錄的名字。 

w 顯示當前工作目錄的路徑。 


這些特殊字符能組合成很多種有用的提示符方案(也可以組合爲很奇異的方案),例如把 PS1 設爲:

PS1="t" 

這導致提示符顯示當前的時間,就象下面的顯示一樣(提示符後面將不會有空格): 

02:16:15 


而下面的設置: 

PS1=t 

將導致提示符變成下面的樣子: 



這顯示了設置中引號的重要性,下面的提示符串: 

PS1="t " 

會使提示符看起來象這個樣子: 

02:16:30 

這種情況下,提示符後面會有一個空格,因爲引號裏有一個空格。 

8,作業控制(Job Control) 


作業控制能夠控制當前正在運行的進程的行爲。特別地,你能把一個正在運行的進程掛起,稍後再恢復它的 
運行。bash保持對所有已啓動的進程的跟蹤,你能在一個正在運行的進程的生命期內的任何時候把它掛起或是使它恢 
復運行。 

按下 Ctrl-Z 使一個運行的進程掛起。bg命令使一個被掛起的進程在後臺恢復運行,反之 fg 命令使進程在 
前臺恢復運行。這幾個命令在當用戶想在後臺運行而意外的把它放到了前臺時,經常被用到。當一個命令在前臺被運 
行時, 它會禁止用戶與 shell的交互,直到該命令結束。這通常不會造成麻煩,因爲大多數命令很快就執行完了。 
如果你要運行的命令要花費很長的時間的話,我們通常會把它放到後臺,以使我們能在前臺繼續輸入其他命令。 

例如,你輸入 這個命令: 

command find / -name "test" > find.out 

它將尋找整個文件系統中的名爲test的文件並把結果保存在一個叫fing.out的文件裏。如果在前臺運行的 
話,根據文件系統的大小,你的shell將有數秒甚至數分鐘不能使用,你不想這樣的話可以再輸入以下面的內容: 

control-z 

bg 

find 命令首先被掛起,再在後臺繼續被執行,並且你能馬上回到bash下。 

六,用戶化配置bash 


本文已經描述了許多用戶化配置bash的方法。但知道現在爲止,我們所做的改動都僅在當前運行的bash下才 
有效。一旦退出系統,所有的改動也隨之消失了。爲了保存這些用戶化配置,你必須把它們保存到一個bash的初始化 
文件裏。 

你能把任何想每次進入cash都執行的命令放到初始化文件裏。這個文件裏最常見到的命令通常是alias和變 
量的初始化。bash的初始化文件叫做 profile。每個使用bash的用戶都有一個.profile文件在他的用戶目錄裏。bash 
在每次啓動時都讀取這個文件,並執行所有包含的命令。 

下面的代碼是缺省的.profile文件的內容。這個文件的位置在/etc目錄。如果你想設置自己的bash 的話把 
它拷到你的用戶目錄裏(如果還沒有的話)並命名爲.profile。 

注意:有些setup程序會在建立用戶時自動放一個.profile文件的拷貝在你的用戶目錄裏。但是並不是所有 
的都這麼做,所以最好先檢查一下你的用戶目錄。記住所有以句點開頭的文件都是隱含的,只有用ls -a或ls -A命令 
才能列出。 


# commands common to all logins 

export OPENWINHOME=/usr/openwin 

export MINICOM="-c on" 

export MANPATH=/usr/local/man:/usr/man/preformat:/usr/man:/X11/man:/usr/openwin /m 
an 

export HOSTNAME="`cat /etc/HOSTNAME`" 

PATH="$PATH:/usr/X11/bin:$OPENWINHOME/bin:/usr/games:." 

LESS=-MM 

# I had problems using eval test instead of TERM=, but you might want to # try 
it anyway. I think with the right /etc/termcap it would work great. # eval tset 
-sQ "$TERM"if [ "$TERM" = "" -o "$TERM" = 
"unknown"]; then 

TERM=linux 

#PS1=hostname:pwd# ` 

if [ "$SHELL" = "/bin/pdksh" -o "$SHELL" = "/bin/ksh" ]; then 

PS1="! $" 

elif [ "$SHELL" = "/bin/zsh" ]; then 

PS1="%m:%~%# " 

elif [ "$SHELL" = "/bin/ash" ]; then 

PS1="$ " 

else 

PS1=h:w$ ` 

fi 

PS2=> ` 

ignoreeof=10 

export PATH DISPLAY LESS TERM PS1 PS2 ignoreeof 

umask 022 

# set up the color-ls environment variables: 

if [ "$SHELL" = "/bin/zsh" l; then 

eval dircolors -z 

elif [ "$SHELL" = "/bin/ash" l; then 

eval dircolors -s 

else 

eval dircolors -b 

fi 

echo 

fortune 

echo 

export TAPE="/dev/nftape" 


七,bash 命令概要 

這是幾個最有用的bash內部命令: 

alias: 設置bash別名。 

bg: 使一個被掛起的進程在後臺繼續執行。 

cd: 改變當前工作目錄。 

exit: 終止shell。 

export: 使變量的值對當前shell的所有子進程都可見 。 

fc: 用來編輯歷史命令列表裏的命令。 

fg: 使一個被掛起的進程在前臺繼續執行。 

help: 顯示bash內部命令的幫助信息。 

kill: 終止某個進程
發佈了37 篇原創文章 · 獲贊 11 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章