什麼是 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 就不能工作