歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> 認識BASH Shell(1)

認識BASH Shell(1)

日期:2017/2/27 9:41:20   编辑:SHELL編程
什麼是 Shell 這應該是個蠻有趣的話題:『什麼是 Shell ?』相信只要摸過電腦,對於作業系統(不論是 Linux 、 Unix 或者是 Windows )有點概念的朋友們大多聽過這個名詞,因為只要有『作業系統』那麼就離不開 Shell 這個東西。不過,在討論 Shell 之前,我們先來了解一下電腦的運作狀況吧!舉個例子來說:當你要電腦傳輸出來『音樂』的時候,你的電腦需要什麼東西呢?1. 當然就是需要你的硬體有『音效卡晶片』這個硬體配備,否則怎麼會有聲音; 2. 作業系統的核心可以支援這個晶片組,當然還需要提供晶片的驅動程式啰; 3. 需要使用者(就是你)輸入發生聲音的指令啰! 這就是基本的一個輸出聲音的需要的步驟!那麼也就是說,你必須要『輸入』一個指令之後,『硬體』才會透過你下達的指令來工作!嘿嘿!那麼硬體如何知道你下達的指令呢?那就是 kernel (核心)的控制工作了!了解了嗎?沒錯!也就是說,我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作!基本上,我們可以透過底下這兩張圖來說明一下:   基本上,替我們工作的是『硬體』,而控制硬體的是『核心』,再來,我們使用者乃是利用『Shell』控制一些 kernel 提供的 『工具 Utility』來操控硬體替我們正確的工作。再舉個例子來說,當我們使用 shell 的功能,輸入『 cd /』來切換目錄時, shell 便利用 kernel 提供的 cd 工具來告訴 kernel 轉換硬碟的工作目錄到 / 當中,然後硬碟就根據 kernel 的掌控而切換到 / 當中啰!這個就是 Shell 的主要功能啰!再進一步來說,由於 kernel 聽不懂人類的語言,而人類也沒有辦法直接記得 kernel 的語言,所以兩者的溝通就得藉由 shell 來支援了!以字面上的意思來說, kernel 是『核心』的意思,而 Shell 是『殼』的意思,呵呵!也就是說, shell 是最外頭的咚咚!而 kernel 乃是最內層的的咚咚啦!核心是作業系統的最底層的東西!這個核心裡頭包括了各種的支援硬體的工具!當然啰,如果你的硬體太新,而你的 kernel 並沒有支援的話,那麼很抱歉,你的 Shell 能力再怎麼強,也沒有辦法使硬體工作的!這樣可以了解了嗎?呵呵!沒錯!使電腦主機工作的正是核心的任務,但是操作核心來替使用者工作的,卻是 shell 喔!因此,有時候你的 shell 搞了老半天,硬體卻不能工作的時候,請注意,您的『核心』是否正確呢?阿!扯遠了!這是 kernel 章節才要說的東西~~BASH Shell 知道什麼是 Shell 之後,那麼我們來了解一下 Linux 使用的是哪一個 shell 呢?什麼!哪一個?難道說 shell 不就是『一個 shell 嗎?』哈哈!那可不!由於早年的 Unix 年代,發展者眾,呵呵!所以由於 shell 依據發展者的不同就有許多的版本,例如常聽到的 Bourne SHell (sh) 、在 Sun 裡頭預設的 C SHell、 商業上常用的 K SHell、, 還有 TCSH 等等,每一種 Shell 都各有其特點。至於 Linux 使用的這一種版本就稱為『 Bourne Again SHell (簡稱 bash ) 』,這個 Shell 是 Bourne Shell 的增強版本,也是基准於 GNU 的架構下發展出來的呦!在介紹 shell 的優點之前,先來說一說 shell 的簡單歷史吧:第一個流行的 shell 是由 Steven Bourne 發展出來的,為了紀念他所以就稱為 Bourne shell ,或直接簡稱為 sh !而後來另一個廣為流傳的 shell 是由柏克萊大學的 Bill Joy 設計依附於 BSD 版的 Unix 系統中的 shell ,這個 shell 的語法有點類似 C 語言,所以才得名為 C shell ,簡稱為 csh !由於在學術界 Sun 主機勢力相當的龐大,而 Sun 主要是 BSD 的分支之一,所以 C shell 也是另一個很重要而且流傳很廣的 shell 之一(因為太多的程式設計師使用的就是 C 語言啦!)!好了,那麼 BASH 是怎麼一回事呢?這個 shell 是 GNU 計畫中重要的工具軟體之一,目前也是 GNU 作業系統中標准的 shell ,他主要相容於 sh 。所以,可想而知的,目前幾乎所有的 Linux distribution 都是使用 bash 作為管理核心的主要 shell 啰!那麼這個 shell 有什麼好處,干嘛 Linux 要使用他作為預設的 shell 呢? BASH 主要的優點有底下幾個: · 命令編修能力(類似 DOS 的 doskey 功能):使用 bash 裡頭,個人認為相當棒的一個功能就是『他能記憶使用過的指令!』這功能真的相當的棒!因為我只要在指令列按『上下鍵』就可以找到前一個輸入的指令!而預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令都被記錄下來了,記錄的檔案在你的家目錄內的 .bash_history !至於這一次登入所執行的指令都被暫存在暫存區中,成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!這有什麼功能呢?最大的好處就是可以『查詢曾經做過的舉動!』,如此可以知道你的執行步驟,那麼就可以追蹤您曾下達的指令,以作為除錯的工具!但如此一來也有個煩惱,就是如果被駭客入侵了,那麼他只要翻你曾經執行過的指令,剛好你的指令又跟系統有關(例如直接輸入 mysql 的密碼在指令列上面)那麼很容易就被破解你的 Linux 主機!所以,最好是將記錄的指令數目減小一點較好! ·檔案比對補全功能(比對資料正確性):這個功能也相當的棒!如果在執行命令的時候不想按下太多的按鍵,例如指令 pcprofiledump 夠長吧!好了,那麼如果你輸入了 pcprofile 之後,再按下 [Tab] 按鍵的話,那麼 bash 馬上會自動的將後面的 dump 接上來!那如果有重復的指令呢?那麼按下兩次 [Tab] 將會把所有重復的指令給他列出來啰! o直接在指令列按下 [Tab][Tab] 兩次,那麼 Linux 將會把系統內的所有執行檔列出來; 另外一個優點就是,可以將該指令所進行的 parameter (與路徑或檔案相關的)比對後,列出正確的項目!舉個例子來說,如果我要列出 /etc/sysconfig/network-scripts 裡面的所有檔案時,要如何下達參數? o ls -al /etc/sysconfig/network-scripts 那我可以在輸入到 network 時按下 [Tab] 按鍵,則 -scripts 就會被自動的加入命令列了!反正真的是蠻方便的,有事沒事多按[tab] 按鍵是不錯的一件事呦!·命令別名(alias)設定功能:假如我需要知道這個目錄底下的所有檔案(包含隱藏檔)及所有的檔案屬性,那麼我就必須要下達 ls -al 這樣的指令列,唉!真麻煩,有沒有更快的取代方式?呵呵!就使用命令別名呀!例如我最喜歡直接以 lm 來取代上面的命令,也就是說, lm 會等於 ls -al 這樣的一個功能,嘿!那麼要如何作呢?就使用 alias 即可!你可以在指令列出入 alias 就可以知道目前的命令別名有哪些了!也可以直接下達命令來設定別名呦: oalias lm='ls -al' ·工作控制 (jobs)、前景背景控制:這部分我們在之後的 指令篇會再提及!使用前、背景的控制可以讓工作進行的更為順利!至於工作控制(jobs)的用途則更廣,可以讓我們隨時將工作丟到背景中執行!而不怕不小心使用了 [Ctrl] + C 來停掉該程序!真是好樣的! ·Shell scripts 的強大功能:在 DOS 年代還記得將一堆指令寫在一起的所謂的『批次檔』吧?在 Linux 底下的 shell scripts 則發揮的更為強大的功能,可以將您日常生活當中常需要下達的連續指令寫成一個檔案,該檔案並且可以透過對談互動式的方式來進行主機的偵測工作!也可以藉由 shell 提供的環境變數及相關指令來進行設計,哇!整個設計下來幾乎就是一個小型的程式語言了!該 scripts 的功能真的是超乎我的想象之外!以前在 DOS 底下需要程式語言才能寫的東西,在 Linux 底下使用簡單的 shell scripts 就可以幫你達成了!真的利害!!這部分我們在底下再來談! 在了解了 BASH 的優點之後,再來我們要來討論的是:那如何在 Shell 提供的環境中下達指令呢?其實很簡單的,下達指令的方式為:   很簡單吧!OK!那麼再來一個問題:『Shell 是什麼時候開始接管 Linux 主機的!?』如果您對於鳥哥前面提到的『開機流程』有稍微去了解一下的話,那麼應該可以了解到 Linux 經由 Kernel 執行完畢,並且執行了 init 與 run-level 設定的一些 scripts 之後,接下來執行了 login 的程式,就可以順利的進入到 shell 接管的程序了!當然啰,要等到使用者順利的登入 Linux 之後,才可以使用 shell 來進行與主機溝通的動作呦!另外,需要注意的是,登入主機之後通常使用者的起始目錄會在『家目錄』, root 的家目錄預設在 /root 底下,一般使用者的家目錄則與 /etc/passwd 的設定有關!變數與變數的設定:echo, env, set, 變數設定規則, eXPort, unset, 再繼續研究 BASH 之前,我們要就變數這個東西來討論一番,因為在主機裡面有太多的資料需要進行存取了,而這些資料都是一些服務所必須的,例如 mail 的存取路徑在 /var/spool/mail 、家目錄預設在 /home/useraccount 等等,當然我們可以改變這些個變數,但是如果該變數是直接深植於套件當中,那麼當你修改了某些參數之後,嘿嘿!你的套件就必須要『由原始碼直接更新再編譯』才行!這樣似乎很麻煩,所以啰,就會有變數這個好東西出來了!  舉個簡單的例子來說, sendmail 的 smtp 存放 mail 路徑是經由 /etc/profile 裡頭的 MAIL="/var/spool/mail/$USER"來設定的,而當我修改了上面這一個咚咚,然後重新開機之後,嘿嘿嘿嘿!我的郵件就可以存放到不同的路徑去了!而且不會有問題!可以順利的『在 Linux 主機上面』收發。然而問題發生在 pop3 這個服務上面,由於 pop3 的預設路徑是在 source code 裡頭,而且就正是 /var/spool/mail 這個路徑,也就是說,不論我怎麼修正我的『變數』, pop3 都不為所動!唉~真慘,所以就無法直接以 pop3 來收信了(例如 Outlook 就不能工作了)!會發生密碼不接受的問題呢!此外,例如我們在執行程式的時候,系統怎麼知道你的 ls 這個指令放在哪裡?原來是有 PATH 這個變數,系統會透過這個變數裡面所設定的路徑去依序尋找該指令系統,如果找不到的話,那麼才在螢幕上顯示『 command not found 』字樣!這些還都只是系統預設的變數的目的,如果是個人的設定方面:例如你要寫一個大型的 script (批次檔)時,有些資料因為可能由於使用者習慣的不同而有差異(例如路徑!),而由於該內容使用在 script 的地方相當的多,如果每次都需要修改該地方,則一定會瘋掉!這個時候使用變數,而將該變數的定義寫在最前面,嘿嘿!那麼你只要修改一行就等於修改整篇 script 了!方便的很!所以,良好的程式設計師都會善用變數的定義!(這個部分我們在底下還會再提到!)如果說的學理一點,那麼由於在 Linux System 下面,所有的執行續都是需要一個執行碼,而就如同上面提到的,你『真正以 shell 來跟 Linux 溝通,是在正確的登入 Linux 之後!』這個時候你就有一個 bash 的執行程序,也才可以真正的經由 bash 來跟系統溝通啰!而在進入 shell 之前,也正如同上面提到的,由於系統需要一些變數來提供他資料的存取(或者是一些環境的設定參數值,例如是否要顯示彩色等等的),所以就有一些所謂的『環境變數』需要來讀入系統中了!說了那麼久,那麼到底『什麼是變數』呢?簡單的說,『變數就是以一組文字或符號等,來取代一些設定或者是一串保留的資料!』,例如:『VBird』就是『鳥哥』,所以當你讀取 VBird 的時候,系統自然就會知道!哈!那就是鳥哥!最簡單的例子可以取 PATH 來說明!如果你對於『相對路徑與絕對路徑』還有點印象的話,那麼應該曉得『要下達正確的指令,應該需要指定路徑與檔名』才行!例如你的 ls 指令應該需要以『/bin/ls』來下達指令才對,那麼為何你在任意的路徑下都可以執行 ls 呢?而不需要指定路徑呢?這是因為系統已經預設了一些『搜尋路徑(PATH)』了,所以當你需要執行一些指令的時候,系統就會依照該 PATH 的設定來進行指令的搜尋!而這個 PATH 就是所謂的變數了!那麼如何『顯示變數』呢?這就需要使用到 echo 這個指令啦! ·echo 顯示變數內容 語法:   就如同上面的范例,當我們要顯示目前的 PATH 這個變數時,使用了 echo ,而為了要分辨是否為變數,那麼 Linux 系統預設變數名稱前面會加上一個『 $ 』符號,所以就必須要寫成 echo $PATH 啰!·有多少的環境變數呀?使用 env 與 set 來看看: 這是我們比較有興趣的,那就是有多少的環境變數在 Linux 系統中呢?呵呵!你可以簡單的使用 env 就可以知道啰!『基本上,在 Linux 預設的情況中,使用{大寫的字母}來設定的變數一般為系統內定需要的變數』,底下列出 Red Hat 7.2 預設的變數內容:·env 顯示目前系統中主要的預設變數內容 語法:    env 這個指令主要在將目前系統中的主要變數讀出來!但是我加上了 sort 就可以將資料進行排序啰!所以像上面的 PATH, USER, HOME 等等的資料就會被讀出來啰!除了 env 這個指令之外,還有一個可以將目前系統中所有的變數資料都讀出來的指令,稱為 set !set 除了會將上面的資料都給他讀出來之外,還會有額外的這些資訊也一起讀入(通常都與使用者的設定有關!): ·set 顯示目前系統中全部的變數內容 語法:   使用 set 除了會將系統的預設值秀出來之外,連帶的所有的你自己設定的變數也會被秀出來!同時需要注意的是,若當時有相當多人同時在線上的話,那麼你的變數只能給自己使用(除非改的是系統的預設參數檔,如 /etc/profile ),而不會干擾到別人的!就如同前面所說的,由於你登入 Linux 之後會取得一個 PID ,而你的設定將只對這個 PID 與子程序有關!此外,這次登入所進行的變數設定,如果沒有更動到設定檔,那麼這次設定的變數在下次登入時將被取消掉(因為程序 PID 不見啰!)!所以啰,如果你想要你的變數每次都能在你登入的時候自動就設定好了,那麼就必須將你的設定寫入登入時載入的設定檔!· 變數設定規則: 好了,我們知道了一些系統的預設變數了,但是如果是我自己想要設定一些我自己的變數,該如何設定呢?有什麼規則需要遵守?呵呵!在說明之前,可能要來讓大家了解一下為什麼自己會想來設定變數?我的案例一:最簡單的例子就是『路徑名稱』啰!以鳥哥為例,我的工作在 Unix 系統之下進行一些數值模式的模擬工作,偏偏由於資料量太大,為了怕日後忘記這個目錄的內容與主要的意義,所以我的檔名都取的很長,偏偏在執行模式的過程中,常常會切換目錄!我哩ㄌㄟ,光是打那幾行路徑名稱就快要瘋掉了!所以我就設定那幾行目錄名稱成為一個四個字元的變數,如此一來我只要輸入『 cd $VARI 』這個指令,嘿嘿!馬上就移動到該路徑下了!很方便吧!當然變數的意義還不止於此,不過這是最簡單的實例說明啰!


什麼是 Shell 這應該是個蠻有趣的話題:『什麼是 Shell ?』相信只要摸過電腦,對於作業系統(不論是 Linux 、 Unix 或者是 Windows )有點概念的朋友們大多聽過這個名詞,因為只要有『作業系統』那麼就離不開 Shell 這個東西。不過,在討論 Shell 之前,我們先來了解一下電腦的運作狀況吧!舉個例子來說:當你要電腦傳輸出來『音樂』的時候,你的電腦需要什麼東西呢?1. 當然就是需要你的硬體有『音效卡晶片』這個硬體配備,否則怎麼會有聲音; 2. 作業系統的核心可以支援這個晶片組,當然還需要提供晶片的驅動程式啰; 3. 需要使用者(就是你)輸入發生聲音的指令啰! 這就是基本的一個輸出聲音的需要的步驟!那麼也就是說,你必須要『輸入』一個指令之後,『硬體』才會透過你下達的指令來工作!嘿嘿!那麼硬體如何知道你下達的指令呢?那就是 kernel (核心)的控制工作了!了解了嗎?沒錯!也就是說,我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作!基本上,我們可以透過底下這兩張圖來說明一下:   基本上,替我們工作的是『硬體』,而控制硬體的是『核心』,再來,我們使用者乃是利用『Shell』控制一些 kernel 提供的 『工具 Utility』來操控硬體替我們正確的工作。再舉個例子來說,當我們使用 shell 的功能,輸入『 cd /』來切換目錄時, shell 便利用 kernel 提供的 cd 工具來告訴 kernel 轉換硬碟的工作目錄到 / 當中,然後硬碟就根據 kernel 的掌控而切換到 / 當中啰!這個就是 Shell 的主要功能啰!再進一步來說,由於 kernel 聽不懂人類的語言,而人類也沒有辦法直接記得 kernel 的語言,所以兩者的溝通就得藉由 shell 來支援了!以字面上的意思來說, kernel 是『核心』的意思,而 Shell 是『殼』的意思,呵呵!也就是說, shell 是最外頭的咚咚!而 kernel 乃是最內層的的咚咚啦!核心是作業系統的最底層的東西!這個核心裡頭包括了各種的支援硬體的工具!當然啰,如果你的硬體太新,而你的 kernel 並沒有支援的話,那麼很抱歉,你的 Shell 能力再怎麼強,也沒有辦法使硬體工作的!這樣可以了解了嗎?呵呵!沒錯!使電腦主機工作的正是核心的任務,但是操作核心來替使用者工作的,卻是 shell 喔!因此,有時候你的 shell 搞了老半天,硬體卻不能工作的時候,請注意,您的『核心』是否正確呢?阿!扯遠了!這是 kernel 章節才要說的東西~~BASH Shell 知道什麼是 Shell 之後,那麼我們來了解一下 Linux 使用的是哪一個 shell 呢?什麼!哪一個?難道說 shell 不就是『一個 shell 嗎?』哈哈!那可不!由於早年的 Unix 年代,發展者眾,呵呵!所以由於 shell 依據發展者的不同就有許多的版本,例如常聽到的 Bourne SHell (sh) 、在 Sun 裡頭預設的 C SHell、 商業上常用的 K SHell、, 還有 TCSH 等等,每一種 Shell 都各有其特點。至於 Linux 使用的這一種版本就稱為『 Bourne Again SHell (簡稱 bash ) 』,這個 Shell 是 Bourne Shell 的增強版本,也是基准於 GNU 的架構下發展出來的呦!在介紹 shell 的優點之前,先來說一說 shell 的簡單歷史吧:第一個流行的 shell 是由 Steven Bourne 發展出來的,為了紀念他所以就稱為 Bourne shell ,或直接簡稱為 sh !而後來另一個廣為流傳的 shell 是由柏克萊大學的 Bill Joy 設計依附於 BSD 版的 Unix 系統中的 shell ,這個 shell 的語法有點類似 C 語言,所以才得名為 C shell ,簡稱為 csh !由於在學術界 Sun 主機勢力相當的龐大,而 Sun 主要是 BSD 的分支之一,所以 C shell 也是另一個很重要而且流傳很廣的 shell 之一(因為太多的程式設計師使用的就是 C 語言啦!)!好了,那麼 BASH 是怎麼一回事呢?這個 shell 是 GNU 計畫中重要的工具軟體之一,目前也是 GNU 作業系統中標准的 shell ,他主要相容於 sh 。所以,可想而知的,目前幾乎所有的 Linux distribution 都是使用 bash 作為管理核心的主要 shell 啰!那麼這個 shell 有什麼好處,干嘛 Linux 要使用他作為預設的 shell 呢? BASH 主要的優點有底下幾個: · 命令編修能力(類似 DOS 的 doskey 功能):使用 bash 裡頭,個人認為相當棒的一個功能就是『他能記憶使用過的指令!』這功能真的相當的棒!因為我只要在指令列按『上下鍵』就可以找到前一個輸入的指令!而預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令都被記錄下來了,記錄的檔案在你的家目錄內的 .bash_history !至於這一次登入所執行的指令都被暫存在暫存區中,成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!這有什麼功能呢?最大的好處就是可以『查詢曾經做過的舉動!』,如此可以知道你的執行步驟,那麼就可以追蹤您曾下達的指令,以作為除錯的工具!但如此一來也有個煩惱,就是如果被駭客入侵了,那麼他只要翻你曾經執行過的指令,剛好你的指令又跟系統有關(例如直接輸入 MySQL 的密碼在指令列上面)那麼很容易就被破解你的 Linux 主機!所以,最好是將記錄的指令數目減小一點較好! ·檔案比對補全功能(比對資料正確性):這個功能也相當的棒!如果在執行命令的時候不想按下太多的按鍵,例如指令 pcprofiledump 夠長吧!好了,那麼如果你輸入了 pcprofile 之後,再按下 [Tab] 按鍵的話,那麼 bash 馬上會自動的將後面的 dump 接上來!那如果有重復的指令呢?那麼按下兩次 [Tab] 將會把所有重復的指令給他列出來啰! o直接在指令列按下 [Tab][Tab] 兩次,那麼 Linux 將會把系統內的所有執行檔列出來; 另外一個優點就是,可以將該指令所進行的 parameter (與路徑或檔案相關的)比對後,列出正確的項目!舉個例子來說,如果我要列出 /etc/sysconfig/network-scripts 裡面的所有檔案時,要如何下達參數? o ls -al /etc/sysconfig/network-scripts 那我可以在輸入到 network 時按下 [Tab] 按鍵,則 -scripts 就會被自動的加入命令列了!反正真的是蠻方便的,有事沒事多按[tab] 按鍵是不錯的一件事呦!·命令別名(alias)設定功能:假如我需要知道這個目錄底下的所有檔案(包含隱藏檔)及所有的檔案屬性,那麼我就必須要下達 ls -al 這樣的指令列,唉!真麻煩,有沒有更快的取代方式?呵呵!就使用命令別名呀!例如我最喜歡直接以 lm 來取代上面的命令,也就是說, lm 會等於 ls -al 這樣的一個功能,嘿!那麼要如何作呢?就使用 alias 即可!你可以在指令列出入 alias 就可以知道目前的命令別名有哪些了!也可以直接下達命令來設定別名呦: oalias lm='ls -al' ·工作控制 (jobs)、前景背景控制:這部分我們在之後的 指令篇會再提及!使用前、背景的控制可以讓工作進行的更為順利!至於工作控制(jobs)的用途則更廣,可以讓我們隨時將工作丟到背景中執行!而不怕不小心使用了 [Ctrl] + C 來停掉該程序!真是好樣的! ·Shell scripts 的強大功能:在 DOS 年代還記得將一堆指令寫在一起的所謂的『批次檔』吧?在 Linux 底下的 shell scripts 則發揮的更為強大的功能,可以將您日常生活當中常需要下達的連續指令寫成一個檔案,該檔案並且可以透過對談互動式的方式來進行主機的偵測工作!也可以藉由 shell 提供的環境變數及相關指令來進行設計,哇!整個設計下來幾乎就是一個小型的程式語言了!該 scripts 的功能真的是超乎我的想象之外!以前在 DOS 底下需要程式語言才能寫的東西,在 Linux 底下使用簡單的 shell scripts 就可以幫你達成了!真的利害!!這部分我們在底下再來談! 在了解了 BASH 的優點之後,再來我們要來討論的是:那如何在 Shell 提供的環境中下達指令呢?其實很簡單的,下達指令的方式為:   很簡單吧!OK!那麼再來一個問題:『Shell 是什麼時候開始接管 Linux 主機的!?』如果您對於鳥哥前面提到的『開機流程』有稍微去了解一下的話,那麼應該可以了解到 Linux 經由 Kernel 執行完畢,並且執行了 init 與 run-level 設定的一些 scripts 之後,接下來執行了 login 的程式,就可以順利的進入到 shell 接管的程序了!當然啰,要等到使用者順利的登入 Linux 之後,才可以使用 shell 來進行與主機溝通的動作呦!另外,需要注意的是,登入主機之後通常使用者的起始目錄會在『家目錄』, root 的家目錄預設在 /root 底下,一般使用者的家目錄則與 /etc/passwd 的設定有關!變數與變數的設定:echo, env, set, 變數設定規則, export, unset, 再繼續研究 BASH 之前,我們要就變數這個東西來討論一番,因為在主機裡面有太多的資料需要進行存取了,而這些資料都是一些服務所必須的,例如 mail 的存取路徑在 /var/spool/mail 、家目錄預設在 /home/useraccount 等等,當然我們可以改變這些個變數,但是如果該變數是直接深植於套件當中,那麼當你修改了某些參數之後,嘿嘿!你的套件就必須要『由原始碼直接更新再編譯』才行!這樣似乎很麻煩,所以啰,就會有變數這個好東西出來了!  舉個簡單的例子來說, sendmail 的 smtp 存放 mail 路徑是經由 /etc/profile 裡頭的 MAIL="/var/spool/mail/$USER"來設定的,而當我修改了上面這一個咚咚,然後重新開機之後,嘿嘿嘿嘿!我的郵件就可以存放到不同的路徑去了!而且不會有問題!可以順利的『在 Linux 主機上面』收發。然而問題發生在 pop3 這個服務上面,由於 pop3 的預設路徑是在 source code 裡頭,而且就正是 /var/spool/mail 這個路徑,也就是說,不論我怎麼修正我的『變數』, pop3 都不為所動!唉~真慘,所以就無法直接以 pop3 來收信了(例如 OutLook 就不能工作了)!會發生密碼不接受的問題呢!此外,例如我們在執行程式的時候,系統怎麼知道你的 ls 這個指令放在哪裡?原來是有 PATH 這個變數,系統會透過這個變數裡面所設定的路徑去依序尋找該指令系統,如果找不到的話,那麼才在螢幕上顯示『 command not found 』字樣!這些還都只是系統預設的變數的目的,如果是個人的設定方面:例如你要寫一個大型的 script (批次檔)時,有些資料因為可能由於使用者習慣的不同而有差異(例如路徑!),而由於該內容使用在 script 的地方相當的多,如果每次都需要修改該地方,則一定會瘋掉!這個時候使用變數,而將該變數的定義寫在最前面,嘿嘿!那麼你只要修改一行就等於修改整篇 script 了!方便的很!所以,良好的程式設計師都會善用變數的定義!(這個部分我們在底下還會再提到!)如果說的學理一點,那麼由於在 Linux System 下面,所有的執行續都是需要一個執行碼,而就如同上面提到的,你『真正以 shell 來跟 Linux 溝通,是在正確的登入 Linux 之後!』這個時候你就有一個 bash 的執行程序,也才可以真正的經由 bash 來跟系統溝通啰!而在進入 shell 之前,也正如同上面提到的,由於系統需要一些變數來提供他資料的存取(或者是一些環境的設定參數值,例如是否要顯示彩色等等的),所以就有一些所謂的『環境變數』需要來讀入系統中了!說了那麼久,那麼到底『什麼是變數』呢?簡單的說,『變數就是以一組文字或符號等,來取代一些設定或者是一串保留的資料!』,例如:『VBird』就是『鳥哥』,所以當你讀取 VBird 的時候,系統自然就會知道!哈!那就是鳥哥!最簡單的例子可以取 PATH 來說明!如果你對於『相對路徑與絕對路徑』還有點印象的話,那麼應該曉得『要下達正確的指令,應該需要指定路徑與檔名』才行!例如你的 ls 指令應該需要以『/bin/ls』來下達指令才對,那麼為何你在任意的路徑下都可以執行 ls 呢?而不需要指定路徑呢?這是因為系統已經預設了一些『搜尋路徑(PATH)』了,所以當你需要執行一些指令的時候,系統就會依照該 PATH 的設定來進行指令的搜尋!而這個 PATH 就是所謂的變數了!那麼如何『顯示變數』呢?這就需要使用到 echo 這個指令啦! ·echo 顯示變數內容 語法:   就如同上面的范例,當我們要顯示目前的 PATH 這個變數時,使用了 echo ,而為了要分辨是否為變數,那麼 Linux 系統預設變數名稱前面會加上一個『 $ 』符號,所以就必須要寫成 echo $PATH 啰!·有多少的環境變數呀?使用 env 與 set 來看看: 這是我們比較有興趣的,那就是有多少的環境變數在 Linux 系統中呢?呵呵!你可以簡單的使用 env 就可以知道啰!『基本上,在 Linux 預設的情況中,使用{大寫的字母}來設定的變數一般為系統內定需要的變數』,底下列出 Red Hat 7.2 預設的變數內容:·env 顯示目前系統中主要的預設變數內容 語法:    env 這個指令主要在將目前系統中的主要變數讀出來!但是我加上了 sort 就可以將資料進行排序啰!所以像上面的 PATH, USER, HOME 等等的資料就會被讀出來啰!除了 env 這個指令之外,還有一個可以將目前系統中所有的變數資料都讀出來的指令,稱為 set !set 除了會將上面的資料都給他讀出來之外,還會有額外的這些資訊也一起讀入(通常都與使用者的設定有關!): ·set 顯示目前系統中全部的變數內容 語法:   使用 set 除了會將系統的預設值秀出來之外,連帶的所有的你自己設定的變數也會被秀出來!同時需要注意的是,若當時有相當多人同時在線上的話,那麼你的變數只能給自己使用(除非改的是系統的預設參數檔,如 /etc/profile ),而不會干擾到別人的!就如同前面所說的,由於你登入 Linux 之後會取得一個 PID ,而你的設定將只對這個 PID 與子程序有關!此外,這次登入所進行的變數設定,如果沒有更動到設定檔,那麼這次設定的變數在下次登入時將被取消掉(因為程序 PID 不見啰!)!所以啰,如果你想要你的變數每次都能在你登入的時候自動就設定好了,那麼就必須將你的設定寫入登入時載入的設定檔!· 變數設定規則: 好了,我們知道了一些系統的預設變數了,但是如果是我自己想要設定一些我自己的變數,該如何設定呢?有什麼規則需要遵守?呵呵!在說明之前,可能要來讓大家了解一下為什麼自己會想來設定變數?我的案例一:最簡單的例子就是『路徑名稱』啰!以鳥哥為例,我的工作在 Unix 系統之下進行一些數值模式的模擬工作,偏偏由於資料量太大,為了怕日後忘記這個目錄的內容與主要的意義,所以我的檔名都取的很長,偏偏在執行模式的過程中,常常會切換目錄!我哩ㄌㄟ,光是打那幾行路徑名稱就快要瘋掉了!所以我就設定那幾行目錄名稱成為一個四個字元的變數,如此一來我只要輸入『 cd $VARI 』這個指令,嘿嘿!馬上就移動到該路徑下了!很方便吧!當然變數的意義還不止於此,不過這是最簡單的實例說明啰!

什麼是 Shell 這應該是個蠻有趣的話題:『什麼是 Shell ?』相信只要摸過電腦,對於作業系統(不論是 Linux 、 Unix 或者是 Windows )有點概念的朋友們大多聽過這個名詞,因為只要有『作業系統』那麼就離不開 Shell 這個東西。不過,在討論 Shell 之前,我們先來了解一下電腦的運作狀況吧!舉個例子來說:當你要電腦傳輸出來『音樂』的時候,你的電腦需要什麼東西呢?1. 當然就是需要你的硬體有『音效卡晶片』這個硬體配備,否則怎麼會有聲音; 2. 作業系統的核心可以支援這個晶片組,當然還需要提供晶片的驅動程式啰; 3. 需要使用者(就是你)輸入發生聲音的指令啰! 這就是基本的一個輸出聲音的需要的步驟!那麼也就是說,你必須要『輸入』一個指令之後,『硬體』才會透過你下達的指令來工作!嘿嘿!那麼硬體如何知道你下達的指令呢?那就是 kernel (核心)的控制工作了!了解了嗎?沒錯!也就是說,我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作!基本上,我們可以透過底下這兩張圖來說明一下:   基本上,替我們工作的是『硬體』,而控制硬體的是『核心』,再來,我們使用者乃是利用『Shell』控制一些 kernel 提供的 『工具 Utility』來操控硬體替我們正確的工作。再舉個例子來說,當我們使用 shell 的功能,輸入『 cd /』來切換目錄時, shell 便利用 kernel 提供的 cd 工具來告訴 kernel 轉換硬碟的工作目錄到 / 當中,然後硬碟就根據 kernel 的掌控而切換到 / 當中啰!這個就是 Shell 的主要功能啰!再進一步來說,由於 kernel 聽不懂人類的語言,而人類也沒有辦法直接記得 kernel 的語言,所以兩者的溝通就得藉由 shell 來支援了!以字面上的意思來說, kernel 是『核心』的意思,而 Shell 是『殼』的意思,呵呵!也就是說, shell 是最外頭的咚咚!而 kernel 乃是最內層的的咚咚啦!核心是作業系統的最底層的東西!這個核心裡頭包括了各種的支援硬體的工具!當然啰,如果你的硬體太新,而你的 kernel 並沒有支援的話,那麼很抱歉,你的 Shell 能力再怎麼強,也沒有辦法使硬體工作的!這樣可以了解了嗎?呵呵!沒錯!使電腦主機工作的正是核心的任務,但是操作核心來替使用者工作的,卻是 shell 喔!因此,有時候你的 shell 搞了老半天,硬體卻不能工作的時候,請注意,您的『核心』是否正確呢?阿!扯遠了!這是 kernel 章節才要說的東西~~BASH Shell 知道什麼是 Shell 之後,那麼我們來了解一下 Linux 使用的是哪一個 shell 呢?什麼!哪一個?難道說 shell 不就是『一個 shell 嗎?』哈哈!那可不!由於早年的 Unix 年代,發展者眾,呵呵!所以由於 shell 依據發展者的不同就有許多的版本,例如常聽到的 Bourne SHell (sh) 、在 Sun 裡頭預設的 C SHell、 商業上常用的 K SHell、, 還有 TCSH 等等,每一種 Shell 都各有其特點。至於 Linux 使用的這一種版本就稱為『 Bourne Again SHell (簡稱 bash ) 』,這個 Shell 是 Bourne Shell 的增強版本,也是基准於 GNU 的架構下發展出來的呦!在介紹 shell 的優點之前,先來說一說 shell 的簡單歷史吧:第一個流行的 shell 是由 Steven Bourne 發展出來的,為了紀念他所以就稱為 Bourne shell ,或直接簡稱為 sh !而後來另一個廣為流傳的 shell 是由柏克萊大學的 Bill Joy 設計依附於 BSD 版的 Unix 系統中的 shell ,這個 shell 的語法有點類似 C 語言,所以才得名為 C shell ,簡稱為 csh !由於在學術界 Sun 主機勢力相當的龐大,而 Sun 主要是 BSD 的分支之一,所以 C shell 也是另一個很重要而且流傳很廣的 shell 之一(因為太多的程式設計師使用的就是 C 語言啦!)!好了,那麼 BASH 是怎麼一回事呢?這個 shell 是 GNU 計畫中重要的工具軟體之一,目前也是 GNU 作業系統中標准的 shell ,他主要相容於 sh 。所以,可想而知的,目前幾乎所有的 Linux distribution 都是使用 bash 作為管理核心的主要 shell 啰!那麼這個 shell 有什麼好處,干嘛 Linux 要使用他作為預設的 shell 呢? BASH 主要的優點有底下幾個: · 命令編修能力(類似 DOS 的 doskey 功能):使用 bash 裡頭,個人認為相當棒的一個功能就是『他能記憶使用過的指令!』這功能真的相當的棒!因為我只要在指令列按『上下鍵』就可以找到前一個輸入的指令!而預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令都被記錄下來了,記錄的檔案在你的家目錄內的 .bash_history !至於這一次登入所執行的指令都被暫存在暫存區中,成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!這有什麼功能呢?最大的好處就是可以『查詢曾經做過的舉動!』,如此可以知道你的執行步驟,那麼就可以追蹤您曾下達的指令,以作為除錯的工具!但如此一來也有個煩惱,就是如果被駭客入侵了,那麼他只要翻你曾經執行過的指令,剛好你的指令又跟系統有關(例如直接輸入 MySQL 的密碼在指令列上面)那麼很容易就被破解你的 Linux 主機!所以,最好是將記錄的指令數目減小一點較好! ·檔案比對補全功能(比對資料正確性):這個功能也相當的棒!如果在執行命令的時候不想按下太多的按鍵,例如指令 pcprofiledump 夠長吧!好了,那麼如果你輸入了 pcprofile 之後,再按下 [Tab] 按鍵的話,那麼 bash 馬上會自動的將後面的 dump 接上來!那如果有重復的指令呢?那麼按下兩次 [Tab] 將會把所有重復的指令給他列出來啰! o直接在指令列按下 [Tab][Tab] 兩次,那麼 Linux 將會把系統內的所有執行檔列出來; 另外一個優點就是,可以將該指令所進行的 parameter (與路徑或檔案相關的)比對後,列出正確的項目!舉個例子來說,如果我要列出 /etc/sysconfig/network-scripts 裡面的所有檔案時,要如何下達參數? o ls -al /etc/sysconfig/network-scripts 那我可以在輸入到 network 時按下 [Tab] 按鍵,則 -scripts 就會被自動的加入命令列了!反正真的是蠻方便的,有事沒事多按[tab] 按鍵是不錯的一件事呦!·命令別名(alias)設定功能:假如我需要知道這個目錄底下的所有檔案(包含隱藏檔)及所有的檔案屬性,那麼我就必須要下達 ls -al 這樣的指令列,唉!真麻煩,有沒有更快的取代方式?呵呵!就使用命令別名呀!例如我最喜歡直接以 lm 來取代上面的命令,也就是說, lm 會等於 ls -al 這樣的一個功能,嘿!那麼要如何作呢?就使用 alias 即可!你可以在指令列出入 alias 就可以知道目前的命令別名有哪些了!也可以直接下達命令來設定別名呦: oalias lm='ls -al' ·工作控制 (jobs)、前景背景控制:這部分我們在之後的 指令篇會再提及!使用前、背景的控制可以讓工作進行的更為順利!至於工作控制(jobs)的用途則更廣,可以讓我們隨時將工作丟到背景中執行!而不怕不小心使用了 [Ctrl] + C 來停掉該程序!真是好樣的! ·Shell scripts 的強大功能:在 DOS 年代還記得將一堆指令寫在一起的所謂的『批次檔』吧?在 Linux 底下的 shell scripts 則發揮的更為強大的功能,可以將您日常生活當中常需要下達的連續指令寫成一個檔案,該檔案並且可以透過對談互動式的方式來進行主機的偵測工作!也可以藉由 shell 提供的環境變數及相關指令來進行設計,哇!整個設計下來幾乎就是一個小型的程式語言了!該 scripts 的功能真的是超乎我的想象之外!以前在 DOS 底下需要程式語言才能寫的東西,在 Linux 底下使用簡單的 shell scripts 就可以幫你達成了!真的利害!!這部分我們在底下再來談! 在了解了 BASH 的優點之後,再來我們要來討論的是:那如何在 Shell 提供的環境中下達指令呢?其實很簡單的,下達指令的方式為:   很簡單吧!OK!那麼再來一個問題:『Shell 是什麼時候開始接管 Linux 主機的!?』如果您對於鳥哥前面提到的『開機流程』有稍微去了解一下的話,那麼應該可以了解到 Linux 經由 Kernel 執行完畢,並且執行了 init 與 run-level 設定的一些 scripts 之後,接下來執行了 login 的程式,就可以順利的進入到 shell 接管的程序了!當然啰,要等到使用者順利的登入 Linux 之後,才可以使用 shell 來進行與主機溝通的動作呦!另外,需要注意的是,登入主機之後通常使用者的起始目錄會在『家目錄』, root 的家目錄預設在 /root 底下,一般使用者的家目錄則與 /etc/passwd 的設定有關!變數與變數的設定:echo, env, set, 變數設定規則, export, unset, 再繼續研究 BASH 之前,我們要就變數這個東西來討論一番,因為在主機裡面有太多的資料需要進行存取了,而這些資料都是一些服務所必須的,例如 mail 的存取路徑在 /var/spool/mail 、家目錄預設在 /home/useraccount 等等,當然我們可以改變這些個變數,但是如果該變數是直接深植於套件當中,那麼當你修改了某些參數之後,嘿嘿!你的套件就必須要『由原始碼直接更新再編譯』才行!這樣似乎很麻煩,所以啰,就會有變數這個好東西出來了!  舉個簡單的例子來說, sendmail 的 smtp 存放 mail 路徑是經由 /etc/profile 裡頭的 MAIL="/var/spool/mail/$USER"來設定的,而當我修改了上面這一個咚咚,然後重新開機之後,嘿嘿嘿嘿!我的郵件就可以存放到不同的路徑去了!而且不會有問題!可以順利的『在 Linux 主機上面』收發。然而問題發生在 pop3 這個服務上面,由於 pop3 的預設路徑是在 source code 裡頭,而且就正是 /var/spool/mail 這個路徑,也就是說,不論我怎麼修正我的『變數』, pop3 都不為所動!唉~真慘,所以就無法直接以 pop3 來收信了(例如 OutLook 就不能工作了)!會發生密碼不接受的問題呢!此外,例如我們在執行程式的時候,系統怎麼知道你的 ls 這個指令放在哪裡?原來是有 PATH 這個變數,系統會透過這個變數裡面所設定的路徑去依序尋找該指令系統,如果找不到的話,那麼才在螢幕上顯示『 command not found 』字樣!這些還都只是系統預設的變數的目的,如果是個人的設定方面:例如你要寫一個大型的 script (批次檔)時,有些資料因為可能由於使用者習慣的不同而有差異(例如路徑!),而由於該內容使用在 script 的地方相當的多,如果每次都需要修改該地方,則一定會瘋掉!這個時候使用變數,而將該變數的定義寫在最前面,嘿嘿!那麼你只要修改一行就等於修改整篇 script 了!方便的很!所以,良好的程式設計師都會善用變數的定義!(這個部分我們在底下還會再提到!)如果說的學理一點,那麼由於在 Linux System 下面,所有的執行續都是需要一個執行碼,而就如同上面提到的,你『真正以 shell 來跟 Linux 溝通,是在正確的登入 Linux 之後!』這個時候你就有一個 bash 的執行程序,也才可以真正的經由 bash 來跟系統溝通啰!而在進入 shell 之前,也正如同上面提到的,由於系統需要一些變數來提供他資料的存取(或者是一些環境的設定參數值,例如是否要顯示彩色等等的),所以就有一些所謂的『環境變數』需要來讀入系統中了!說了那麼久,那麼到底『什麼是變數』呢?簡單的說,『變數就是以一組文字或符號等,來取代一些設定或者是一串保留的資料!』,例如:『VBird』就是『鳥哥』,所以當你讀取 VBird 的時候,系統自然就會知道!哈!那就是鳥哥!最簡單的例子可以取 PATH 來說明!如果你對於『相對路徑與絕對路徑』還有點印象的話,那麼應該曉得『要下達正確的指令,應該需要指定路徑與檔名』才行!例如你的 ls 指令應該需要以『/bin/ls』來下達指令才對,那麼為何你在任意的路徑下都可以執行 ls 呢?而不需要指定路徑呢?這是因為系統已經預設了一些『搜尋路徑(PATH)』了,所以當你需要執行一些指令的時候,系統就會依照該 PATH 的設定來進行指令的搜尋!而這個 PATH 就是所謂的變數了!那麼如何『顯示變數』呢?這就需要使用到 echo 這個指令啦! ·echo 顯示變數內容 語法:   就如同上面的范例,當我們要顯示目前的 PATH 這個變數時,使用了 echo ,而為了要分辨是否為變數,那麼 Linux 系統預設變數名稱前面會加上一個『 $ 』符號,所以就必須要寫成 echo $PATH 啰!·有多少的環境變數呀?使用 env 與 set 來看看: 這是我們比較有興趣的,那就是有多少的環境變數在 Linux 系統中呢?呵呵!你可以簡單的使用 env 就可以知道啰!『基本上,在 Linux 預設的情況中,使用{大寫的字母}來設定的變數一般為系統內定需要的變數』,底下列出 Red Hat 7.2 預設的變數內容:·env 顯示目前系統中主要的預設變數內容 語法:    env 這個指令主要在將目前系統中的主要變數讀出來!但是我加上了 sort 就可以將資料進行排序啰!所以像上面的 PATH, USER, HOME 等等的資料就會被讀出來啰!除了 env 這個指令之外,還有一個可以將目前系統中所有的變數資料都讀出來的指令,稱為 set !set 除了會將上面的資料都給他讀出來之外,還會有額外的這些資訊也一起讀入(通常都與使用者的設定有關!): ·set 顯示目前系統中全部的變數內容 語法:   使用 set 除了會將系統的預設值秀出來之外,連帶的所有的你自己設定的變數也會被秀出來!同時需要注意的是,若當時有相當多人同時在線上的話,那麼你的變數只能給自己使用(除非改的是系統的預設參數檔,如 /etc/profile ),而不會干擾到別人的!就如同前面所說的,由於你登入 Linux 之後會取得一個 PID ,而你的設定將只對這個 PID 與子程序有關!此外,這次登入所進行的變數設定,如果沒有更動到設定檔,那麼這次設定的變數在下次登入時將被取消掉(因為程序 PID 不見啰!)!所以啰,如果你想要你的變數每次都能在你登入的時候自動就設定好了,那麼就必須將你的設定寫入登入時載入的設定檔!· 變數設定規則: 好了,我們知道了一些系統的預設變數了,但是如果是我自己想要設定一些我自己的變數,該如何設定呢?有什麼規則需要遵守?呵呵!在說明之前,可能要來讓大家了解一下為什麼自己會想來設定變數?我的案例一:最簡單的例子就是『路徑名稱』啰!以鳥哥為例,我的工作在 Unix 系統之下進行一些數值模式的模擬工作,偏偏由於資料量太大,為了怕日後忘記這個目錄的內容與主要的意義,所以我的檔名都取的很長,偏偏在執行模式的過程中,常常會切換目錄!我哩ㄌㄟ,光是打那幾行路徑名稱就快要瘋掉了!所以我就設定那幾行目錄名稱成為一個四個字元的變數,如此一來我只要輸入『 cd $VARI 』這個指令,嘿嘿!馬上就移動到該路徑下了!很方便吧!當然變數的意義還不止於此,不過這是最簡單的實例說明啰!



Copyright © Linux教程網 All Rights Reserved