bash 基本觀念

来源:百度文库 编辑:神马文学网 时间:2024/04/28 23:34:22
May 05, 2007
bash 基本觀念
何謂 shell ?
以 Unix-Like 的作業系統為例,shell 是介於使用者與 OS 之間的的交談介面。所有來自使用者的指令,都會被 shell 轉換為 OS 可以認得的命令並執行,相對的,OS 所回傳的內容自然也會被 shell 轉換為使用者可以辨識的訊息。
以下用一張簡單的圖來說明使用者、shell、OS 三者的關係:

shell 其中一個很重要的工作,就是將使用者所下達的指令,轉換為可以交由 OS 所執行的命令,以下用一個簡單的 command 為例:
shell> sort -n phonelist > phonelist.sorted
以上指令的作用,在於將 phonelist 檔案中的內容,以數字大小進行排列後,輸出至檔案 phonelist.sorted 中。
而 shell 是如何將此段指令進行轉換呢? 它做了以下步驟:
將整段指令分解為「sort」、「-n」、「phonelist」、「>」、「phonelist.sorted」五個部分,每個部分皆稱為 word。
判斷每個 word 的目的為何:
「sort」是排序的指令、「-n」以及「phonelist」是參數、「>」以及「phonelist.sorted」被合在一起視為一個 I/O 的指令。
啟動一個 I/O 的動作,準備將內容寫入 phonelist.sorted 中。
開始將原檔案進行排序。
每個步驟的執行細節就不在這邊介紹,這裡只是要表達出 shell 在 parse 一個指令大概的流程為何。
bash 的特色與優點
在之後針對 shell 的介紹,都是以 bash 為主,因為它是目前最流行的 shell,功能也相對最為強大;而到底 bash 有哪些特色與優點呢? 以下有兩篇好文章,說明的相當詳細:
Shell by OSL3
使用 bash 的優點
檔案
在 bash 中,檔案被分為三種,分別是純文字檔、執行檔(binary)、以及目錄(directory),其中目錄結構在學習 Linux 上是個相當重要的議題,不過這邊並不贅述,主要把重心放在 bash 上,而且盡量寫些大家容易忘記的部分。
所以像是符號「~」代表使用者家目錄,這種很基本的觀念,就不再多著墨了!
【備註】在 Unix-Like 的檔案系統,沒有所謂的「副檔名」,並非像 Windows 一樣,*.txt 代表純文字檔、*.exe 代表執行檔....等等,這是必須注意的!
1、檔案名稱與萬用字元
首先,要說明的是隱藏檔,在 Windows 中,隱藏檔是以檔案的屬性來決定;不過在 Linux 中,隱藏檔的檔名則是以「.」作為開頭。
接著介紹萬用字元(wildcard),基本的萬用字元有以下幾種:
萬用字元
符合的內容
任何單一字元
*
一個或多個任何字元
[set]
符合[set]中設定的任何字元
[!set]
不符合[set]中設定的任何字元
其中 ? 與 * 的差別就是符合單一字元或是多個字元而已,以下介紹 [set] 的用法:
[set] 描述 符合的內容
[abc] a or b or c
[.,;] 句號 or 逗號 or 分號
[-_] 減號 or 底線
[a-c] a or b or c
[a-z] 任一小寫英文字母
[!0-9] 任一非數字字元
[0-9!] 任一數字 or 驚嘆號
[a-zA-Z] 任一英文字母
[a-zA-Z0-9_-] 任一英文字母 or 數字 or 底線 or 減號
以下用個簡單例子來說明,假設有兩個目錄 /home/user1 以及 /home/user2,想要一次把這兩個目錄列表出來,可以用下指令:
shell> ls /home/user*
假如又要列出上述兩個目錄中,名稱為 a 或是 c 開頭的目錄或檔案,可用以下指令:
shell> ls /home/user*/[ac]*
其他的應用,就是由使用者自行去發揮了!
2、Brace Expansion
在 bash 3.0 以後,提供了 Brace Expansion 的功能,它是以左右大括號來設定字元的篩選條件,的用法跟 wildcard 有點不太一樣,以下直接用範例來說明:
Brace Expansion
符合的內容
b{ed,olt,ar}s
beds, bolts, bars
b{ar{d,n,k},ed}s
bards, barns, baeks, beds
{2..5} 2 or 3 or 4 or 5
{d..h}
d or e or f or g or h
輸入與輸出(I/O)
1、Standard I/O
所謂的 standard Input,可能是來自使用者的鍵盤、或是某個檔案內容; standard output 可能就是使用者的螢幕、印表機、或是其他輸出設備....等等,不過這些都是基本的,一般的 shell 都一定會支援的。
而為了讓 I/O 在使用上更有彈性,bash 支援了 pipeline(管線) 的功能,透過 pipeline 的方式,可以將多個程式結合起來,將 A 程式的 output 當作是 B 程式的 input,如此一來,就可以藉由此方式來完成更複雜的 I/O 工作了! 例:將 mail 檔案中的內容直接透過 lp 指令輸出到印表機上,而不是顯示在螢幕上。
pipeline 的支援,讓許多複雜的 I/O 工作變得容易完成,加上之後會介紹的 filtering 的功能(Linux 中有許多用在 filtering 的指令,例如:cat、grep、sort、cut、sed、tr....等等),便可以撰寫 shell script 來自動完成許多日常工作。
2、I/O Redirection
redirection 的功能可用來取代原本的 standard input 以及 standard output,分別以符號「<」代表 input,符號「>」代表 output,以下用個範例來說明:
shell> cat < file1 > file2
上述指令會將 file1 的內容複製一份變成 file2,效果等同一下的指令:
shell> cp file1 file2
瞭解了嗎? 在 bash shell 中,I/O 是可以做很多不同變化的。
3、Pipeline
在 standard I/O 中就有提到 pipeline 啦! 它的作用就是將某支程式所產生出來的 output 丟給另一支程式作為 input,所使用的符號為「|」,透過此符號將兩個以上不同的指令連結起來,讓前面指令的 output 成為下一個指令的 input。
以下舉個簡單例子:
shell> ls -al /home | more
此指令會將 /home 目錄中的子目錄以及檔案通通列出來,包含隱藏檔,但是若內容很多,超過畫面一頁可以顯示的範圍,就透過 pipeline,將輸出交給 more 指令來做分頁瀏覽的效果,甚至可以交由 lp 指令直接從印表機輸出。
不過當然實際情況不會這麼簡單,在舉個例子,以儲存使用者帳號資訊的檔案 /etc/passwd 為例,每個使用者的帳號都會一行一行的存於此檔案中,格式如下:
man:x:6:12:man:/var/cache/man:/bin/sh
每行中都包含著非常多的資訊,並且以冒號(:)作為間隔,至於這些資訊代表什麼意思,這邊不多做探討,假設我們只需要使用者帳號的部分,如果管理者希望將使用者帳號以字母的順序作排序後,並交由印表機列印出來,則可透過以下指令來完成:
shell> cut -d: -f1 < /etc/passwd | sort | lp
# 以下指令跟上面的相同
shell> cut -d: -f1 /etc/passwd | sort | lp
看見了嗎? 在指令中把 redirection 跟 pipeline 的功能一起用上了! 如此一來達成我們想要的效果。當然,更複雜的指令也是可以完成,只是這就必須要透過大家的巧思了。
工作管理
由於 Unix-Like 系統強大的工作管理功能,不但讓使用者可以下指令同時做多個工作,也可以讓多個不同使用者同時登入,每個使用者有不同的 login session,可說是真正的 Multi-User 的操作環境。
在下指令進行某工作時,一般正常情況下,必須等到工作處理結束,才可以下另一個指令,但若是工作要處理很久的(例如:大型檔案的搬移),那可就要等半天囉! 但若不想這樣等,可以在指令的最後加上符號「&」,如此一來,工作就會移至背景去執行,馬上就可以下達下一個指令來處理另外一個工作了!
而透過加入符號「&」的指令所處理的工作,會產生一個 process number,供使用者隨時檢視之用,還可以使用renice 的指令調整工作的處理優先權;此外,若要瞭解目前移至背景處理的工作的狀況,可用指令jobs 來檢視。
不過需要注意的是,一般的 I/O 工作並不適合移到背景去執行,原因如下:
因為假如被移到背景的 I/O 工作需要使用者的 input,此時整個工作就會 stop,直到使用者將工作刪除,或是移回前景(foreground)來處理才會繼續。
假設被移至背景處理的 I/O 工作有任何資料要輸出時,一樣會出現在使用者的螢幕上,這樣一來,就會跟使用者正在處理的工作所產生的訊息混合輸出,造成螢幕訊息很混亂。不過這當然這也不是沒有解決方法,只要利用 redirection 的方式將輸出訊息轉到檔案或是 /dev/null 中,就可以解決此問題了!
特殊字元及引號
Unix-Like 系統提供了強大的功能,當然也需要有許多不同的特殊符號來搭配使用,例如「<」以及「>」使用來處理 I/O redirection,「&」則是將工作移至背景處理....等等,以下介紹各種不同特殊字元及引號的用法:
字元
功能說明
~
home directory
`
command substitution
#
comment
$
variable expression
&
background job
*
string wildcard
(
start subshell
)
end subshell
\
quote next character
|
pipe
[
start character-set wildcard
]
end character-set wildcard
{
start command block
}
end command block
;
shell command separator
'
strong quote
<">
weak quote
<
input redirect
>
output redirect
/
pathname directory separator
single-character wildcard
!
pipeline logical NOT
1、引號與跳脫字元的使用
當使用者要在螢幕上單純顯示上述這些符號,為了讓 shell 不會誤判為特殊用途,必須搭配引號以及跳脫字元使用,假設我們要在螢幕上輸出「2 * 3 > 5 is a valid inquality」這一行訊息,其中包含了「*」及「>」兩個特殊字元,以下用幾個例子說明:
# 無法顯示正確訊息,反而會有其他非預期的訊息輸出至名稱為「5」的檔案中
shell> echo 2 * 3 > 5 is a valid inquality
# 正確顯示
shell> echo '2 * 3 > 5 is a valid inquality'
# 正確顯示
shell> '2 * 3 > 5' is a valid inquality
# 正確顯示
shell> echo 2 \* 3 \> 5 is a valid inquality假設要顯示的訊息中,有引號呢? 如果這次訊息換成「"2 * 3 > 5" is a valid inquality」,這就一定非得要跳脫字元的協助不可了,可用以下指令來完成此需求:
shell> echo \"2 \* 3 \> 5\" is a valid inquality
2、指令過長的處理方式
當使用者下的指令很長時,應該要怎麼處理呢? 這時候可以使用反斜線(\),也就是要使用跳脫字元所用的反斜線,shell 會認為指令尚未結束,讓使用者在下一行繼續輸入。
3、控制鍵
控制鍵可以在許多情況下可能會用到,例如:不小心下錯指令,要趕快停止時,按 Ctrl+C 停止指令的執行;或是想要暫停目前的工作,可按 Ctrl+Z.....等等,善用這些熱鍵,可讓工作更為順利,以下介紹常用的控制鍵:
控制鍵
功能說明
Ctrl + C
終止目前執行中的命令
Ctrl + D
結束輸入
Ctrl + \
終止目前執行中的命令(假設 Ctrl+C 沒有效用的話)
Ctrl + S
停止螢幕輸出訊息
Ctrl + Q
重新輸出訊息至螢幕
Del or Ctrl + ?
清除最後一個字元
Ctrl + U
清除目前命令列中的指令
Ctrl + Z
暫停目前的工作
參考資料:
認識 Bash Shell
GNU Bash
Shell by OSL3
使用 bash 的優點
Learning the bash Shell, Third Edition

 
Read More...
Collapse...
張貼者:曾建銘 
Post a Comment