一.BASH和Shell

我們在第一章 Linux 是什麼當中提到了: 管理整個電腦硬體的其實是作業系統的核心 (kernel),這個核心是需要被保護的! 所以我們一般使用者就只能透過 shell 來跟核心溝通,以讓核心達到我們所想要達到的工作。 那麼系統有多少 shell 可用呢?為什麼我們要使用 bash 啊?底下分別來談一談喔!

①shell 硬件 核心

這應該是個蠻有趣的話題:『什麼是 Shell 』?相信只要摸過電腦,對於作業系統 (不論是 Linux 、 Unix 或者是 Windows) 有點概念的朋友們大多聽過這個名詞,因為只要有『作業系統』那麼就離不開 Shell 這個東西。不過,在討論 Shell 之前,我們先來瞭解一下電腦的運作狀況吧! 舉個例子來說:當你要電腦傳輸出來『音樂』的時候,你的電腦需要什麼東西呢?

  1. 硬體:當然就是需要你的硬體有『音效卡晶片』這個配備,否則怎麼會有聲音;
  2. 核心管理:作業系統的核心可以支援這個晶片組,當然還需要提供晶片的驅動程式囉;
  3. 應用程式:需要使用者 (就是你) 輸入發生聲音的指令囉!

這就是基本的一個輸出聲音所需要的步驟!也就是說,你必須要『輸入』一個指令之後, 『硬體』才會透過你下達的指令來工作!那麼硬體如何知道你下達的指令呢?那就是 kernel (核心) 的控制工作了!也就是說,我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作! 基本上,我們可以透過底下這張圖來說明一下:

Linux(5)认识与学习BASH

man, chmod, chown, vi, fdisk, mkfs 等等指令,這些指令都是獨立的應用程式, 但是我們可以透過殼程式 (就是指令列模式) 來操作這些應用程式,讓這些應用程式呼叫核心來運作所需的工作哩!

②shell的历史

第一個流行的 shell 是由 Steven Bourne 發展出來的,為了紀念他所以就稱為 Bourne shell ,或直接簡稱為 sh !而後來另一個廣為流傳的 shell 是由柏克萊大學的 Bill Joy 設計依附於 BSD 版的 Unix 系統中的 shell ,這個 shell 的語法有點類似 C 語言,所以才得名為 C shell ,簡稱為 csh !由於在學術界 Sun 主機勢力相當的龐大,而 Sun 主要是 BSD 的分支之一,所以 C shell 也是另一個很重要而且流傳很廣的 shell 之一 。

③系统的合法shell

能够使用的shell被记录在etc/shells里面

Linux(5)认识与学习BASH

二.Bash shell的功能

①history

bash 的功能裡頭,鳥哥個人認為相當棒的一個就是『他能記憶使用過的指令!』 這功能真的相當的棒!因為我只要在指令列按『上下鍵』就可以找到前/後一個輸入的指令!而在很多 distribution 裡頭,預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令幾乎都被記錄下來了。

這麼多的指令記錄在哪裡呢?在你的家目錄內的 .bash_history 啦! 不過,需要留意的是,~/.bash_history 記錄的是前一次登入以前所執行過的指令, 而至於這一次登入所執行的指令都被暫存在記憶體中,當你成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!

這有什麼優點呢?最大的好處就是可以『查詢曾經做過的舉動!』 如此可以知道你的執行步驟,那麼就可以追蹤你曾下達過的指令,以作為除錯的重要流程! 但如此一來也有個煩惱,就是如果被駭客入侵了,那麼他只要翻你曾經執行過的指令, 剛好你的指令又跟系統有關 (例如直接輸入 MySQL 的密碼在指令列上面),那你的伺服器可就傷腦筋了! 到底記錄指令的數目越多還是越少越好?這部份是見仁見智啦,沒有一定的答案的。

②命令补全tab

  • [Tab] 接在一串指令的第一個字的後面,則為命令補全;
  • [Tab] 接在一串指令的第二個字以後時,則為『檔案補齊』!
  • 若安裝 bash-completion 軟體,則在某些指令後面使用 [tab] 按鍵時,可以進行『選項/參數的補齊』功能!

③alias别名设定功能

  • alias lm='ls -al'

④工作控制

比如ctrl+c用来停掉某个程序

⑤shell scripts

三.指令

①type:判断指令是外部指令还是bash的内建指令

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

②换行、快速删除

换行 : /(反斜杠)+[Enter]

快速删除: 

Linux(5)认识与学习BASH

四.变量

變數是 bash 環境中非常重要的一個玩意兒,我們知道 Linux 是多人多工的環境,每個人登入系統都能取得一個 bash shell, 每個人都能夠使用 bash 下達 mail 這個指令來收受『自己』的郵件等等。問題是, bash 是如何得知你的郵件信箱是哪個檔案? 這就需要『變數』的幫助。

环境变量:PATH, HOME, MAIL, SHELL等。

①变量的取用echo

可以利用 echo 這個指令來取用變數, 但是,變數在被取用時,前面必須要加上錢字號『 $ 』才行。

Linux(5)认识与学习BASH

②变量的设定=

Linux(5)认识与学习BASH

  1. 變數與變數內容以一個等號『=』來連結,如下所示: 
    『myname=VBird』
     
  2. 等號兩邊不能直接接空白字元,如下所示為錯誤: 
    『myname = VBird』或『myname=VBird Tsai』
     
  3. 變數名稱只能是英文字母與數字,但是開頭字元不能是數字,如下為錯誤: 
    『2myname=VBird』
     
  4. 變數內容若有空白字元可使用雙引號『"』或單引號『'』將變數內容結合起來,但
    • 雙引號內的特殊字元如 $ 等,可以保有原本的特性,如下所示:
      『var="lang is $LANG"』則『echo $var』可得『lang is zh_TW.UTF-8』
    • 單引號內的特殊字元則僅為一般字元 (純文字),如下所示:
      『var='lang is $LANG'』則『echo $var』可得『lang is $LANG』
  5. 可用跳脫字元『 \ 』將特殊符號(如 [Enter], $, \, 空白字元, '等)變成一般字元,如:
    『myname=VBird\ Tsai』
     
  6. 在一串指令的執行中,還需要藉由其他額外的指令所提供的資訊時,可以使用反單引號『`指令`』或 『$(指令)』。特別注意,那個 ` 是鍵盤上方的數字鍵 1 左邊那個按鍵,而不是單引號! 例如想要取得核心版本的設定:
    『version=$(uname -r)』再『echo $version』可得『3.10.0-229.el7.x86_64』
     
  7. 若該變數為擴增變數內容時,則可用 "$變數名稱" 或 ${變數} 累加內容,如下所示:
    『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』
     
  8. 若該變數需要在其他子程序執行,則需要以 export 來使變數變成環境變數:Linux(5)认识与学习BASH
    『export PATH』
  9. 通常大寫字元為系統預設變數,自行設定變數可以使用小寫字元,方便判斷 (純粹依照使用者興趣與嗜好) ;
     
  10. 取消變數的方法為使用 unset :『unset 變數名稱』例如取消 myname 的設定:
    『unset myname』

Linux(5)认识与学习BASH

③env和set

使用env查看环境变量

Linux(5)认识与学习BASH

  • HOME
    代表使用者的家目錄。還記得我們可以使用 cd ~ 去到自己的家目錄嗎?或者利用 cd 就可以直接回到使用者家目錄了。那就是取用這個變數啦~ 有很多程式都可能會取用到這個變數的值!
     
  • SHELL
    告知我們,目前這個環境使用的 SHELL 是哪支程式? Linux 預設使用 /bin/bash 的啦!
     
  • HISTSIZE
    這個與『歷史命令』有關,亦即是, 我們曾經下達過的指令可以被系統記錄下來,而記錄的『筆數』則是由這個值來設定的。
     
  • MAIL
    當我們使用 mail 這個指令在收信時,系統會去讀取的郵件信箱檔案 (mailbox)。
     
  • PATH
    就是執行檔搜尋的路徑啦~目錄與目錄中間以冒號(:)分隔, 由於檔案的搜尋是依序由 PATH 的變數內的目錄來查詢,所以,目錄的順序也是重要的喔。
     
  • LANG
    這個重要!就是語系資料囉~很多訊息都會用到他, 舉例來說,當我們在啟動某些 perl 的程式語言檔案時,他會主動的去分析語系資料檔案, 如果發現有他無法解析的編碼語系,可能會產生錯誤喔!一般來說,我們中文編碼通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,這兩個編碼偏偏不容易被解譯出來,所以,有的時候,可能需要修訂一下語系資料。 這部分我們會在下個小節做介紹的!
     
  • RANDOM
    這個玩意兒就是『隨機亂數』的變數啦!目前大多數的 distributions 都會有亂數產生器,那就是/dev/random 這個檔案。 我們可以透過這個亂數檔案相關的變數 ($RANDOM) 來隨機取得亂數值喔。在 BASH 的環境下,這個 RANDOM 變數的內容,介於 0~32767 之間,所以,你只要 echo $RANDOM 時,系統就會主動的隨機取出一個介於 0~32767 的數值。

使用set查看所有变量

④命令提示字元PS1:自己看这个舒服就行

這個東西就是我們的『命令提示字元』喔! 當我們每次按下 [Enter] 按鍵去執行某個指令後,最後要再次出現提示字元時, 就會主動去讀取這個變數值了。上頭 PS1 內顯示的是一些特殊符號,這些特殊符號可以顯示不同的資訊, 每個 distributions 的 bash 預設的 PS1 變數內容可能有些許的差異,不要緊,『習慣你自己的習慣』就好了。

  • \d :可顯示出『星期 月 日』的日期格式,如:"Mon Feb 2"
  • \H :完整的主機名稱。舉例來說,鳥哥的練習機為『study.centos.vbird』
  • \h :僅取主機名稱在第一個小數點之前的名字,如鳥哥主機則為『study』後面省略
  • \t :顯示時間,為 24 小時格式的『HH:MM:SS』
  • \T :顯示時間,為 12 小時格式的『HH:MM:SS』
  • \A :顯示時間,為 24 小時格式的『HH:MM』
  • \@ :顯示時間,為 12 小時格式的『am/pm』樣式
  • \u :目前使用者的帳號名稱,如『dmtsai』;
  • \v :BASH 的版本資訊,如鳥哥的測試主機版本為 4.2.46(1)-release,僅取『4.2』顯示
  • \w :完整的工作目錄名稱,由根目錄寫起的目錄名稱。但家目錄會以 ~ 取代;
  • \W :利用 basename 函數取得工作目錄名稱,所以僅會列出最後一個目錄名。
  • \# :下達的第幾個指令。
  • \$ :提示字元,如果是 root 時,提示字元為 # ,否則就是 $ 囉~

⑤子程序

當你登入 Linux 並取得一個 bash 之後,你的 bash 就是一個獨立的程序,這個程序的識別使用的是一個稱為程序識別碼,被稱為 PID 的就是。 接下來你在這個 bash 底下所下達的任何指令都是由這個 bash 所衍生出來的,那些被下達的指令就被稱為子程序了。 我們可以用底下的圖示來簡單的說明一下父程序與子程序的概念:

Linux(5)认识与学习BASH

上所示,我們在原本的 bash 底下執行另一個 bash ,結果操作的環境介面會跑到第二個 bash 去(就是子程序), 那原本的 bash 就會在暫停的情況 (睡著了,就是 sleep)。若要回到原本的 bash 去, 就只有將第二個 bash 結束掉 (下達 exit 或 logout) 才行。

⑥从外部读取变量

输入read KING , 再输入hggggc敲打回车:

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

⑦说明变量的类型

declare 或 typeset指令

Linux(5)认识与学习BASH

  • 變數類型預設為『字串』,所以若不指定變數類型,則 1+2 為一個『字串』而不是『計算式』。
  • bash 環境中的數值運算,預設最多僅能到達整數形態,所以 1/3 結果是 0;

⑧数组

Linux(5)认识与学习BASH

⑨变量内容的删除

Linux(5)认识与学习BASH

  • # :符合取代文字的『最短的』那一個;
  • ##:符合取代文字的『最長的』那一個

上面談到的是『從前面開始刪除變數內容』,那麼如果想要『從後面向前刪除變數內容』呢? 這個時候就得使用百分比 (%) 符號了!來看看範例四怎麼做吧!

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

五.限制

想像一個狀況:我的 Linux 主機裡面同時登入了十個人,這十個人不知怎麼搞的, 同時開啟了 100 個檔案,每個檔案的大小約 10MBytes ,請問一下, 我的 Linux 主機的記憶體要有多大才夠? 10*100*10 = 10000 MBytes = 10GBytes ... 老天爺,這樣,系統不掛點才有鬼哩!為了要預防這個情況的發生,所以我們的 bash 是可以『限制使用者的某些系統資源』的,包括可以開啟的檔案數量, 可以使用的 CPU 時間,可以使用的記憶體總量等等。如何設定?用 ulimit 吧!

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

六.history指令

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

七.BASH shell的操作环境

①进站欢迎

bash 也有進站畫面與歡迎訊息喔?真假?真的啊! 還記得在終端機介面 (tty1 ~ tty6) 登入的時候,會有幾行提示的字串嗎?那就是進站畫面啊! 那個字串寫在哪裡啊?呵呵!在 /etc/issue 裡面

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

使用vim修改/etc/issue文件

Linux(5)认识与学习BASH

进入tty3:

Linux(5)认识与学习BASH

②环境设定

1.login和non-login shell

  • login shell:取得 bash 時需要完整的登入流程的,就稱為 login shell。舉例來說,你要由 tty1 ~ tty6 登入,需要輸入使用者的帳號與密碼,此時取得的 bash 就稱為『 login shell 』囉;
     
  • non-login shell:取得 bash 介面的方法不需要重複登入的舉動,舉例來說,(1)你以 X window 登入 Linux 後, 再以 X 的圖形化介面啟動終端機,此時那個終端介面並沒有需要再次的輸入帳號與密碼,那個 bash 的環境就稱為 non-login shell了。(2)你在原本的 bash 環境下再次下達 bash 這個指令,同樣的也沒有輸入帳號密碼, 那第二個 bash (子程序) 也是 non-login shell 。

為什麼要介紹 login, non-login shell 呢?這是因為這兩個取得 bash 的情況中,讀取的設定檔資料並不一樣所致。 由於我們需要登入系統,所以先談談 login shell 會讀取哪些設定檔?一般來說,login shell 其實只會讀取這兩個設定檔:

  1. /etc/profile:這是系統整體的設定,你最好不要修改這個檔案;
  2. ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:屬於使用者個人設定,你要改自己的資料,就寫入這裡!

2.login shell的流程图

Linux(5)认识与学习BASH

3.non-login shell

③终端机的环境设定

可以在 tty1 ~ tty6 這六個文字介面的終端機 (terminal) 環境中登入,登入的時候我們可以取得一些字元設定的功能。比如:我們可以利用倒退鍵 (backspace,就是那個←符號的按鍵) 來刪除命令列上的字元, 也可以使用 [ctrl]+c 來強制終止一個指令的運行,當輸入錯誤時,就會有聲音跑出來警告。這是怎麼辦到的呢? 很簡單啊!因為登入終端機的時候,會自動的取得一些終端機的輸入環境的設定啊!

stty指令(setting tty)可以用来设置终端机

Linux(5)认识与学习BASH

  • intr  : 送出一個 interrupt (中斷) 的訊號給目前正在 run 的程序 (就是終止囉!);
  • quit  : 送出一個 quit 的訊號給目前正在 run 的程序;
  • erase : 向後刪除字元,
  • kill  : 刪除在目前指令列上的所有文字;
  • eof   : End of file 的意思,代表『結束輸入』。
  • start : 在某個程序停止後,重新啟動他的 output
  • stop  : 停止目前螢幕的輸出;
  • susp  : 送出一個 terminal stop 的訊號給正在 run 的程序。

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

⑤通配符

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

八.资料流重定向

①输出

资料流重定向就是把某个指令执行后应该要出现在屏幕上的资料,传输到其他地方去,例如档案、装置等。

Linux(5)认识与学习BASH

standard output(标准输出):指令执行所回传的正确的信息

standard error output(标准错误输出):指令执行失败后,所回传的错误信息

  1. 標準輸入  (stdin) :代碼為 0 ,使用 < 或 << ;
  2. 標準輸出  (stdout):代碼為 1 ,使用 > 或 >> ;
  3. 標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ;

建立保存输出讯息的文件:Linux(5)认识与学习BASH

制定输出到该文件中:Linux(5)认识与学习BASH

使用vim进入文件:

Linux(5)认识与学习BASH

  1. 該檔案 (本例中是 ./redirect.txt) 若不存在,系統會自動的將他建立起來,但是
  2. 當這個檔案存在的時候,那麼系統就會先將這個檔案內容清空,然後再將資料寫入!
  3. 也就是若以 > 輸出到一個已存在的檔案中,那個檔案就會被覆蓋掉囉!

那如果我想要將資料累加而不想要將舊的資料刪除,那該如何是好?利用兩個大於的符號 (>>) 就好啦!以上面的範例來說,你應該要改成『 ll / >> ~/rootfile 』即可。 如此一來,當 (1) ~/rootfile 不存在時系統會主動建立這個檔案;(2)若該檔案已存在, 則資料會在該檔案的最下方累加進去!

②垃圾桶黑洞

如果我知道錯誤訊息會發生,所以要將錯誤訊息忽略掉而不顯示或儲存呢? 這個時候黑洞裝置 /dev/null 就很重要了!這個 /dev/null 可以吃掉任何導向這個裝置的資訊

③错误和正确同时写入某文件

Linux(5)认识与学习BASH

④输入

利用cat建立档案的时候,会叫你从键盘输入内容:

Linux(5)认识与学习BASH

如果想直接从档案里面读取内容来写入cat新建的这个文件:

Linux(5)认识与学习BASH

查看文件大小:

Linux(5)认识与学习BASH

使用<<读入:

他代表的是『結束的輸入字元』的意思!舉例來講:『我要用 cat 直接將輸入的訊息輸出到 catfile 中, 且當由鍵盤輸入 eof 時,該次輸入就結束』,那我可以這樣做:

Linux(5)认识与学习BASH

九.命令的执行

①顺序执行:Linux(5)认识与学习BASH---------->分号

②条件执行:如果两个指令之间有关系:

兩個指令之間有相依性,而這個相依性主要判斷的地方就在於前一個指令執行的結果是否正確

Linux(5)认识与学习BASH

&&,因为第一个文件夹不存在,所以后一条指令并没有执行

Linux(5)认识与学习BASH

||,虽然第一个文件夹不存在,但是后一条指令执行成功

Linux(5)认识与学习BASH

十.管线命令:pipe

①|指令

管線命令『 | 』僅能處理經由前面一個指令傳來的正確資訊,也就是 standard output 的資訊,對於 stdandard error 並沒有直接處理的能力。

Linux(5)认识与学习BASH

补充:

more功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上。 more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能 。more命令从前向后读取文件,因此在启动时就加载整个文件。

less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大。less 的用法比起 more 更加的有弹性。 在 more 的时候,我们并没有办法向前面翻, 只能往后面看,但若使用了 less 时,就可以使用 [pageup] [pagedown] 等按 键的功能来往前往后翻看文件,更容易用来查看一个文件的内容!除此之外,在 less 里头可以拥有更多的搜索功能,不止可以向下搜,也可以向上搜。

  • 管線命令僅會處理 standard output,對於 standard error output 會予以忽略
  • 管線命令必須要能夠接受來自前一個指令的資料成為 standard input 繼續處理才行。

②cut和grep指令

cut 不就是『切』嗎?沒錯啦!這個指令可以將一段訊息的某一段給他『切』出來~ 處理的訊息是以『行』為單位

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

如果不用 | 指令,则是在最后加上文档名

Linux(5)认识与学习BASH

剛剛的 cut 是將一行訊息當中,取出某部分我們想要的,而 grep 則是分析一行訊息, 若當中有我們所需要的資訊,就將該行拿出來~簡單的語法是這樣的,grep用于搜索多一点。

Linux(5)认识与学习BASHLinux(5)认识与学习BASH

③排序指令sort、wc、uniq

1.sort

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

2.uniq

如果我排序完成了,想要將重複的資料僅列出一個顯示:

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

3.wc

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

④双向重定向

想個簡單的東西,我們由前一節知道 > 會將資料流整個傳送給檔案或裝置,因此我們除非去讀取該檔案或裝置, 否則就無法繼續利用這個資料流。萬一我想要將這個資料流的處理過程中將某段訊息存下來,應該怎麼做? 利用 tee 就可以囉~我們可以這樣簡單的看一下:

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

用vim进入teeTest.txt:

Linux(5)认识与学习BASH

⑤字元转换命令

1.tr

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

2.col

Linux(5)认识与学习BASH

3.join

Linux(5)认识与学习BASH

4.paste

Linux(5)认识与学习BASH

5.

Linux(5)认识与学习BASH

⑥分割指令split

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

Linux(5)认识与学习BASH

⑦参数代换:xargs

xargs 是在做什麼的呢?就以字面上的意義來看, x 是加減乘除的乘號,args 則是 arguments (參數) 的意思,所以說,這個玩意兒就是在產生某個指令的參數的意思! xargs 可以讀入 stdin 的資料,並且以空白字元或斷行字元作為分辨,將 stdin 的資料分隔成為 arguments 。 因為是以空白字元作為分隔,所以,如果有一些檔名或者是其他意義的名詞內含有空白字元的時候, xargs 可能就會誤判了~他的用法其實也還滿簡單的!就來看一看先!

Linux(5)认识与学习BASH

 

相关文章: