1灰嫉、bash 與 shell
管理整個計算機硬件的其實是操作系統(tǒng)的內核(Kernel)状蜗,這個內核是需要被保護的,所以我們一般用戶就只能通過shell來跟內核通信除呵,讓內核達到我們想要達到的工作再菊。
1.1、硬件颜曾,內核與shell
我們必須通過 shell 將我們輸入的命令與內核通信纠拔,好讓內核可以控制硬件來正確無誤的工作。
操作系統(tǒng)其實是一組軟件稠诲,由于這組軟件在控制整個硬件與管理系統(tǒng)的活動監(jiān)測侦鹏。如果這組軟件能被用戶隨意操作,若用戶應用不當臀叙,將會使得整個系統(tǒng)奔潰略水。因為操縱系統(tǒng)管理的就是整個硬件功能,所以當然不能夠被隨便一些沒有管理能力的終端用戶隨意使用劝萤。
但我們總是需要讓用戶操作系統(tǒng)的渊涝,所以就有了在操作系統(tǒng)上面發(fā)展的應用程序。用戶可以通過應用程序來指揮內核床嫌,讓內核達到我們所需要的硬件任務跨释。
如圖所示,其實應用程序在最外層厌处,就如同雞蛋的外殼一樣鳖谈,因此這個也就被稱為shell。
也就是說嘱蛋,只要能夠操作應用程序的接口都能夠稱為shell蚯姆。狹義的shell指的是命令行方面的軟件,包括bash等洒敏。廣義的shell則包括圖形界面的軟件龄恋。
1.2、為何要學習命令界面的shell
命令行界面的shell:各個distribution 都一樣凶伙;
遠程管理:命令行界面就是比較快郭毕;
Linux的任督二脈:shell是也;
1.3函荣、系統(tǒng)的合法shell與/etc/shells功能
由于shell依據發(fā)布者的不同就有許多版本显押,例如 Bourne SHell (sh)、C SHell傻挂、K SHell乘碑、TCSH等。
Linux默認使用的這一版本就是 Bourne Again SHell(bash)金拒,這個shell是 Bourne SHell 的增強版兽肤,也是基于GNU框架下發(fā)展出來的。
cat ?/etc/shells ? ?#檢查系統(tǒng)有多少個可以使用的shell
為什么我們系統(tǒng)上合法的shell要寫入/etc/shells這個文件绪抛?這是因為系統(tǒng)某些服務在運行過程中资铡,會去檢查用戶能夠使用的shells,而這些shell的查詢就是借助/etc/shells這個文件幢码。
我這個用戶什么時候可以取得shell權限呢笤休?默認又會取得哪一種shell呢?
cat ?/etc/passwd
每一行的最后一個數據症副,就是你可以取得的默認的shell店雅。
1.4政基、bash shell 的功能
bash是GNU計劃中重要的工具軟件之一,目前也是Linux distributions 的標準shell底洗。bash主要兼容于sh腋么,并且依據一些用戶的需求而加強shell 版本。
bash的主要優(yōu)點:
命令記憶能力(history)亥揖;
命令與文件補全功能(【tab】按鍵的好處)珊擂;
命令別名設置功能(alias); ? ?# alias ?ll='ls -l'
作業(yè)控制费变、前臺摧扇、后臺控制(job control, foreground,background);
使用前臺物延、后臺的控制可以讓作業(yè)進行得更為順利。至于作業(yè)控制(jobs)的用途更廣在张,可以讓我們隨時將工作丟到后臺中執(zhí)行,而不怕不小心使用 ctrl + c ?來中斷該進程矮慕。此外也可以在單一登錄的環(huán)境中達到多任務的目的呢帮匾!
程序腳本(shell ?script);# 還記得DOS下的批處理文件嗎痴鳄?Linux下的shell script 則發(fā)揮更為強大的功能瘟斜。
通配符(Wildcard);
1.5痪寻、bash shell 的內置命令:type
判定一個命令是來自于外部命令(非bash所提供的命令)或是內置在bash當中的呢螺句?利用type這個命令來查看即可。
type 主要在找出“執(zhí)行文件”而不是一般文件名橡类,所以type也可以用來作為類似which命令的用途蛇尚。
1.6、命令的執(zhí)行
如果命令串太長的話顾画,如何使用兩行來輸出取劫?
cp ?/var/spool/mail/root ?/etc/crontab ?\
> ?/etc/fstab ?/root
上面的命令是將三個文件復制到/root這個目錄下來,不過因為命令太長亲雪,我們就利用 “ \[Enter] " 勇凭,用轉義符 " \ "來將 " [Enter]"轉義疚膊,讓 [Enter] 按鍵不再具有“開始執(zhí)行”的功能义辕。
特別要注意 轉義字符 ?" \ ",這非常重要寓盗。
2灌砖、shell 的變量功能
2.1璧函、什么是變量
y=ax+b,其中左邊的y就是變量基显,右邊的(ax+b)就是變量內容蘸吓。左邊是未知數,右邊是已知數撩幽。
變量就是以一組文字或符號等库继,來替代一些設置或者是一串保留的數據。
講的更簡單一點窜醉,我們可以用一個簡單的“字眼”來替代另一個比較復雜或者是容易變動的數據宪萄。這樣最大的好處就是方便。
變量的可變性與方便性榨惰;
影響bash環(huán)境操作的變量拜英;
腳本程序設計的好幫手;
2.2變量的顯示與設置:echo琅催、unset
你可以利用 ?echo ?這個命令來顯示變量居凶,但是變量在被顯示的時候,前面必須要加上字符 "$" 才行藤抡。
echo ?$PATH
echo ?$HOME
myname=Zhang
echo ?$myname
在bash中侠碧,當一個變量名稱尚未被設置時,默認的內容是”空“的杰捂。
變量的設置規(guī)則
1舆床,變量與變量內容以一個等號”=“來連接,如myname=zhang嫁佳;
2挨队,等號兩邊不能直接接空格符,否則錯誤蒿往;
3盛垦,變量名稱只能是英文字母和數字,但是開頭字符不能是數字瓤漏;
4腾夯,變量內容若有空格可使用 ?雙引號”“ ?或者單引號‘’ 將變量內容結合起來;
雙引號 " " 內的特殊符號(如$等)蔬充,可以保有原本的特性蝶俱。
單引號 ' ' 內的特殊字符則僅為一般字符(純文本)。
5饥漫,可用轉義字符 "\"將特殊符號(如 [Enter]榨呆、$、\庸队、空格符积蜻、闯割!等)變成一般字符;
6竿拆,在一串命令中宙拉,還需要通過其他命令提供的信息,可以使用 反單引號 ` `(~符號鍵丙笋,在1旁邊谢澈,tab上邊);
7御板,若該變量為了增加變量內容時澳化,則可用 $變量名稱 ?或 ?${變量} 累加內容;
8稳吮,若該變量需要在其他子進程執(zhí)行缎谷,則需要以 export 來使變量變成環(huán)境變量;
9灶似,通常大寫字符為系統(tǒng)默認變量列林,自行設置變量可以使用小寫字符,方便判斷酪惭;
0希痴,取消標量的方法為使用 ?unset 變量名,如 unset myname春感;
什么是子進程砌创?就是說在我目前這個shell的情況下,去打開另一個新的shell鲫懒,新的那個shell就是子進程嫩实。在一般狀態(tài)下,父進程定義的變量是無法在子進程內使用的窥岩,要通過 export 將變量變成環(huán)境變量后才可以甲献。
在一串命令中,在 反引號 `` 內的命令將被優(yōu)先執(zhí)行颂翼,而其執(zhí)行結果將作為外部的輸入信息晃洒。
特別注意 單引號,雙引號朦乏,反引號?所代表的意思球及。
2.3、環(huán)境變量的功能
環(huán)境變量可以幫我們達到很多功能呻疹,包括主文件夾的變換吃引、提示符的顯示、執(zhí)行文件查找的路徑等。
用env(environment)查看環(huán)境變量與常見環(huán)境變量說明:
HOME ?代表用戶主目錄际歼;
SHELL ?告知我們目前這個環(huán)境使用的shell是哪個程序;
HISTSIZE ?這個與歷史命令有關姑蓝;
PATH ?就是執(zhí)行文件查找的路勁鹅心;
LANG ?系統(tǒng)語系數據;
RANDOM ?這是隨機數變量纺荧;
用set查看所有變量(含環(huán)境變量和自定義變量)
PS1這個是我們的命令提示符旭愧,PS2是第二行的提示符;
PS1:(提示字符的配置)
這是 PS1 (數字的 1 不是英文字母)宙暇,這個東西就是我們的『命令提示字符』喔输枯! 當我們每次按下 [Enter] 按鍵去運行某個命令后,最后要再次出現提示字符時占贫, 就會主動去讀取這個變量值了桃熄。上頭 PS1 內顯示的是一些特殊符號,這些特殊符號可以顯示不同的信息型奥, 每個 distributions 的 bash 默認的 PS1 變量內容可能有些許的差異瞳收,不要緊,『習慣你自己的習慣』就好了厢汹。 你可以用 man bash (注3)去查詢一下 PS1 的相關說明螟深,以理解底下的一些符號意義。
\d :可顯示出『星期 月 日』的日期格式烫葬,如:"Mon Feb 2"
\H :完整的主機名界弧。舉例來說,鳥哥的練習機為『www.vbird.tsai』
\h :僅取主機名在第一個小數點之前的名字搭综,如鳥哥主機則為『www』后面省略
\t :顯示時間垢箕,為 24 小時格式的『HH:MM:SS』
\T :顯示時間,為 12 小時格式的『HH:MM:SS』
\A :顯示時間兑巾,為 24 小時格式的『HH:MM』
\@ :顯示時間舰讹,為 12 小時格式的『am/pm』樣式
\u :目前使用者的賬號名稱,如『root』闪朱;
\v :BASH 的版本信息月匣,如鳥哥的測試主板本為 3.2.25(1),僅取『3.2』顯示
\w :完整的工作目錄名稱奋姿,由根目錄寫起的目錄名稱锄开。但家目錄會以 ~ 取代;
\W :利用 basename 函數取得工作目錄名稱称诗,所以僅會列出最后一個目錄名萍悴。
\# :下達的第幾個命令。
\$ :提示字符,如果是 root 時癣诱,提示字符為 # 计维,否則就是 $ 啰~
好了,讓我們來看看 CentOS 默認的 PS1 內容吧:『[\u@\h \W]\$ 』撕予,現在你知道那些反斜杠后的數據意義了吧鲫惶? 要注意喔!那個反斜杠后的數據為 PS1 的特殊功能实抡,與 bash 的變量配置沒關系啦欠母!不要搞混了喔! 那你現在知道為何你的命令提示字符是:『 [root@www ~]# 』了吧吆寨?
$:(關于本 shell 的 PID)
錢字號本身也是個變量喔赏淌!這個咚咚代表的是『目前這個 Shell 的線程代號』,亦即是所謂的 PID (Process ID)啄清。 更多的程序觀念六水,我們會在第四篇的時候提及。想要知道我們的 shell 的 PID 辣卒,就可以用:『 echo $$ 』即可缩擂!出現的數字就是你的 PID 號碼。
什么添寺?問號也是一個特殊的變量胯盯?沒錯!在 bash 里面這個變量可重要的很计露! 這個變量是:『上一個運行的命令所回傳的值』博脑, 上面這句話的重點是『上一個命令』與『回傳值』兩個地方。當我們運行某些命令時票罐, 這些命令都會回傳一個運行后的代碼叉趣。一般來說,如果成功的運行該命令该押, 則會回傳一個 0 值疗杉,如果運行過程發(fā)生錯誤,就會回傳『錯誤代碼』才對蚕礼!
OSTYPE, HOSTTYPE, MACHTYPE:(主機硬件與核心的等級)
由于不同等級的 CPU 命令集不太相同烟具,因此你的軟件可能會針對某些 CPU 進行優(yōu)化,以求取較佳的軟件性能奠蹬。 所以軟件就有 i386, i686 及 x86_64 之分朝聋。
要留意的是,較高階的硬件通常會向下兼容舊有的軟件囤躁,但較高階的軟件可能無法在舊機器上面安裝冀痕!
export: 自定義變量轉成環(huán)境變量
因為子進程僅會繼承父進程的環(huán)境變量荔睹,子進程不會繼承父進程的自定義變量,所以需要使用 export 命令言蛇。
export ?變量名稱僻他;
2.4、影響顯示結果的語系變量(locale)
locale ?腊尚;
設置LANG的時候吨拗,其他的語系變量就會被這個變量所替代。
2.5跟伏、變量的有效范圍
某些書籍會談到 全局變量(global variable)和 局部變量(local variable),基本上可以這么理解翩瓜,
環(huán)境變量=全局變量受扳;
自定義變量=局部變量;
2.6兔跌、變量鍵盤讀取勘高、數組與聲明:read,array坟桅,declare
read
要讀取來自鍵盤輸入的變量华望,就是用read這個命令。
declare / typeset
declare 或 typeset 是一樣的功能仅乓,就是在『聲明變量的類型』
變量類型默認為 字符串赖舟,所以若不指定變量類型,則 1+2 為一個字符串而不是計算式夸楣;
bash 環(huán)境中的數值運算宾抓,默認最多僅能到達整數類型,所以 1/3 結果為 0豫喧;
數組(array)變量類型:
某些時候石洗,我們必須使用數組來宣告一些變量。
數組的變量類型比較有趣的地方在于『讀取』紧显,一般來說讲衫,建議直接以 ${數組} 的方式來讀取,比較正確無誤的啦孵班!
3涉兽、命令別名與歷史命令
3.1、命令別名設置:alias篙程,unalias
命令別名是一個很有趣的東西花椭,特別是你的慣用命令特別長的時候》课纾或者給命令增設默認選項的時候矿辽。
alias ?ll='ls ?-l'
source ~/.bashrc
查看系統(tǒng)別名情況
unalias ?ll ? ? #取消ll命令別名
3.2、歷史命令:history
查看使用過的歷史命令
history
那么history命令只可以讓我們查詢命令而已嗎?當然不止袋倔。我們可以利用相關的功能來幫我們執(zhí)行歷史命令雕蔽。
基本上history命令用途很大,但是需要小心安全的問題宾娜,尤其是root的歷史紀錄文件批狐,這是Cracker的最愛。因為不小心 root 會將很多的重要數據在執(zhí)行的過程中記錄在 ~/.bash_history當中前塔,如果這個文件被解析的話嚣艇,后果不堪設想。
無論如何华弓,使用history配置 食零!曾經使用的命令執(zhí)行是很有效率的。
4寂屏、Bash Shell的操作環(huán)境
是否記得我們登錄主機的時候屏幕上面會有一些說明文字贰谣,并且登錄的時候還可以給用戶提供一些信息或者歡迎文字。此外我們習慣的環(huán)境變量迁霎,命令別名等是否可以登錄就主動幫我們設置好吱抚?
4.1、路徑與命令查找順序
命令的運行順序基本上可以這樣看:
1考廉,以絕對/相對路徑執(zhí)行命令秘豹;
2,由alias找到該命令來執(zhí)行昌粤;
3憋肖,由bash內置的(builtin)命令來執(zhí)行;
4婚苹,通過$PATH這個變量的順序找到的第一個命令來執(zhí)行
4.2岸更、bash的登錄與歡迎信息:/etc/issue,/etc/motd
還記得在終端接口登錄時候的歡迎信息嗎膊升?它在 /etc/issue 里面怎炊。可對此進行自定義廓译。
cat ?/etc/issue
如果你想要讓用戶登錄后取得一些信息评肆,例如你想要讓大家都知道的信息,那么可以將信息加入 /etc/motd 里去非区。所有用戶都會顯示這個信息瓜挽。
vi ? /etc/motd
4.3、bash的環(huán)境配置文件
操作系統(tǒng)有一些環(huán)境配置文件的存在征绸,讓bash在啟動時直接讀取這些配置文件久橙,以規(guī)劃好bash的操作環(huán)境俄占。而這些配置文件又可以分為全體系統(tǒng)的配置文件以及用戶個人偏好配置文件。要注意的是淆衷,我們前幾個小時談到的命令別名缸榄、自定義的變量在你注銷bash后就會失效,所以你想要保留你的設置祝拯,就得要將這些設置寫入配置文件才行甚带。
login shell 和 non-login shell
取得bash時需要完整的登錄流程,就稱為login shell佳头。
取得bash接口的方法不需要重復登錄的舉動鹰贵,就稱為 non-login shell。
記住幾個組合按鍵:
4.4康嘉、通配符與特殊符號
通配符(wildcard)是一個非常有用的功能碉输。
bash中常見的特殊符號。理論上凄鼻,你的文件名盡量不要使用到上述的字符腊瑟。
5聚假、數據流重定向
數據流重定向就是將某個命令執(zhí)行后應該要出現在屏幕上的數據傳輸到其他的地方块蚌,l例如文件或者是設備。這玩意兒在Linux的文本模式下面可重要的膘格,尤其是如果我們想要將某些數據保存下來時峭范,就更有用了。
5.1瘪贱、什么是數據流重定向
Standard output (標準輸出)和 Standard error (標準錯誤)都是默認輸出到屏幕上面來的纱控。
簡單來說,標準輸出指的是命令執(zhí)行所回傳的正確信息菜秦,而標準錯誤輸出可理解為命令執(zhí)行失敗后甜害,所回傳的錯誤信息。
標準輸入(stdin):代碼為0球昨,使用 < 或者 <<尔店;
標準輸出(stdout):代碼為1,使用 > 或者 >>主慰;
標準錯誤(stderr):代買為2嚣州,使用 2> 或者 2>>;
">" 表示以覆蓋方式寫入共螺,">>"表示以追加方式寫入该肴。
將標準輸出和錯誤輸出寫入不同文件:
find ?/home -name .bashrc > right.txt 2> error.txt
如果要將正確與錯誤寫入相同文件:
find /home -name .bashrc > /dev/null 2>&1
/dev/null 垃圾桶黑洞設備與特殊寫法,這個/dev/null 可以吃掉任何導向這個設備的信息藐不。
Standard input(標準輸入):將原本由鍵盤輸入的數據改由文件的內容來替代匀哄。
cat ?> ?catfile ?< ?~/abc.txt
5.2秦效、命令執(zhí)行的判斷依據: “;” ? “&&” ? “||”
在某些情況下拱雏,我們想一次性輸入多個命令去執(zhí)行棉安,有兩個選擇。
1铸抑、cmd贡耽; ?cmd ? ?#不考慮命令相關性的連續(xù)命令執(zhí)行
如:sync; shutdown -h now
在命令與命令中利用分號(鹊汛;)來隔開蒲赂,這樣一來,分號前的命令執(zhí)行完后就會立刻接著執(zhí)行后面的命令了刁憋。Linux下命令是由左往右走執(zhí)行的滥嘴。
2、$?(命令回傳碼)與 && 或 ||
若前一個命令執(zhí)行的結果為正確至耻,在Linux下面會回傳一個 $?=0 的值若皱。
5.3、雙重定向
想要將數據流處理過程中將某段信息存下來尘颓,就可以利用 tee命令走触。
tee 命令會同時將數據流送與 文件 和 屏幕(screen)
6、管道命令(pipe)
管道命令使用 " | " 這個界定符號疤苹。
其實管道命令" | " 僅能處理經由前面一個命令傳來的正確信息互广,也就是 Standard output的信息,對于 Standard error并沒有直接處理的能力卧土。
在每個管道后面接的第一個數據必定是”命令“惫皱,而且這個命令必須要能夠接收 standard input 的數據才行,這樣的命令才可以是”管道命令“尤莺。
6.1旅敷、選取命令:cut,grep
什么是選取命令颤霎,說穿了媳谁,就是講一段數據經過分析后,取出我們所想要的捷绑,或者是經由分析關鍵字韩脑,去得我們所想要的那一行。
cut 命令
這個命令可以將一段信息的某一段”切“出來粹污,處理的信息是以”行“為單位段多。
cut 主要的用途在于將同一行里面的數據進行分解,最常使用在分析一些數據或文字數據的時候壮吩。
grep 命令
grep 是分析一行信息进苍,若當中有我們所需要的信息加缘,就將該行拿出來。
grep 可以解析一行文字觉啊,去得關鍵字拣宏,若該行有存在
6.2、排序命令:sort杠人,wc勋乾,uniq
sort 是很有趣的命令,它可以幫助我們進行排序嗡善,而且可以依據不同的數據類型來排序辑莫。
uniq,排序完成后罩引,想將重復的數據僅列出一個顯示各吨。
wc,知道文件里面有多少行袁铐,多少字揭蜒,多少多少字符。
重點回顧:
由于內核在內存中是受保護的塊剔桨,因此我們必須要通過”Shell“將我們輸入的命令與Kernel通信屉更,好讓Kernel可以控制硬件來正確無誤地工作。
學習Shell的主要原因有:命令行界面的shell在各大distribution都一樣领炫;遠程管理時命令行界面速度較快偶垮;shell是管理Linux系統(tǒng)非常重要的一環(huán)张咳,因為Linux內很多控制都是以shell編寫的帝洪。
系統(tǒng)合法的shell均寫在/etc/shell文件中。
用戶默認登陸取得的shell記錄于/etc/passwd的最后一個字段脚猾。
bash的功能主要有命令編輯功能葱峡、命令與文件補全功能、命令別名設置功能龙助、作業(yè)控制砰奕、前臺、后臺控制提鸟、程序化腳本军援、通配符。
type可以用來找到執(zhí)行命令為何種類型称勋,也可用于與which相同的功能胸哥。
變量就是以一組文字或符號等來替換一些設置或者是一串保留的數據。
變量主要有環(huán)境變量和自定義變量赡鲜,或稱為全局變量和局部變量空厌。
使用 env(environment)與export可查看環(huán)境變量庐船,其中export可以將自定義變量轉換成環(huán)境變量。
set 可以查看目前bash環(huán)境下的所有變量嘲更。
$?也為變量筐钟,是前一個命令執(zhí)行完畢后的回傳碼。在Linux回傳碼為0代表執(zhí)行成功赋朦。
locale可用于查看語系數據篓冲。
可用read讓用戶由鍵盤輸入變量的值。
ulimit 可用以限制用戶使用系統(tǒng)的資源情況宠哄。
bash的配置文件主要分為 loginshell 與 non-login shell纹因。 login shell 主要讀取 /etc/profile 與 ~/.bash_profile,non-login shell 則僅讀取 ~/.bashrc琳拨。
通配符主要有 * ?瞭恰? ?[ ]等。
數據流重定向通過 >狱庇、2>惊畏、< 之類的符號將輸出的信息轉到其他文件夾或設備去撬陵。
連續(xù)命令的執(zhí)行可通過:&&雇寇,||等符號來處理衅胀。
管道命令的重點是它僅會處理 standard output愉豺,對于 standard error output 會予以忽略挠日。管道命令必須要能偶接收來自前一個命令的數據成為 standard input繼續(xù)處理才行虹曙。