一辆沦,Shell 是一種腳本語言
有的編程語言,如 C/C++肢扯、Pascal、Go語言乍钻、匯編等,必須在程序運行之前將所有代碼都翻譯成二進制形式银择,也就是生成可執(zhí)行文件,用戶拿到的是最終生成的可執(zhí)行文件夹孔,看不到源碼析孽。
這個過程叫做 編譯(Compile),這樣的編程語言叫做 編譯型語言袜瞬,完成編譯過程的軟件叫做編譯器(Compiler)。
而有的編程語言佑菩,如 Shell裁赠、JavaScript殿漠、Python佩捞、PHP等,需要一邊執(zhí)行一邊翻譯莲蜘,不會生成任何可執(zhí)行文件帘营,用戶必須拿到源碼才能運行程序。程序運行后會即時翻譯芬迄,翻譯完一部分執(zhí)行一部分,不用等到所有代碼都翻譯完杜窄。
這個過程叫做 解釋算途,這樣的編程語言叫做 解釋型語言 或者 腳本語言(Script),完成解釋過程的軟件叫做解釋器嘴瓤。
站在這個角度講莉钙,Shell 也是一種編程語言筛谚,它的編譯器(解釋器)是 Shell 這個程序胆胰。我們平時所說的 Shell刻获,有時候是指連接用戶和內(nèi)核的這個程序瞎嬉,有時候又是指 Shell 編程。
編譯型語言的優(yōu)點是執(zhí)行速度快氧枣、對硬件要求低、保密性好扎谎,適合開發(fā)操作系統(tǒng)、大型應(yīng)用程序毁靶、數(shù)據(jù)庫等逊移。
腳本語言的優(yōu)點是使用靈活、部署容易胳泉、跨平臺性好,非常適合Web開發(fā)以及小工具的制作扇商。
二,Shell 與 Linux 運維工程師(OPS)
Linux被廣泛地用于服務(wù)器端蔬芥,OPS 的主要工作就是維護應(yīng)用的運行環(huán)境控汉,包括安裝操作系統(tǒng)/部署和維護代碼的運行依賴/修復(fù)漏洞防止服務(wù)器被攻擊/監(jiān)控服務(wù)器壓力,別讓服務(wù)器宕機/分析日志暇番,及時發(fā)現(xiàn)代碼或者環(huán)境的問題。
因為 OPS 面對的可能是成千上萬臺的服務(wù)器次酌,很難通過人工手段逐個維護,所以通過一份代碼讓指定服務(wù)器完成相同工作就非常重要岳服。例如服務(wù)的監(jiān)控、代碼快速部署纲辽、服務(wù)啟動停止璃搜、數(shù)據(jù)備份、日志分析等这吻。
Shell 腳本很適合處理純文本類型的數(shù)據(jù),而 Linux 中幾乎所有的配置文件怠硼、日志文件(如 NFS移怯、Rsync、Httpd舟误、Nginx、MySQL 等)同云,以及絕大多數(shù)的啟動文件都是純文本類型的文件堵腹。在運維過程中,若把上述文件內(nèi)容比作珍珠疚顷,那么 Shell 就是將珍珠連接成手鏈的繩索。
Python 不但可以用于腳本程序開發(fā)阀坏,也可以實現(xiàn) Web 程序開發(fā)(知乎笆檀、豆瓣、YouTube酗洒、Instagram 都是用 Python 開發(fā))枷遂,甚至還可以實現(xiàn)軟件的開發(fā)(大名鼎鼎的 OpenStack棋嘲、SaltStack 都是 Python 語言開發(fā))、游戲開發(fā)痪伦、大數(shù)據(jù)開發(fā)雹锣、移動端開發(fā)网沾。每一個運維人員在熟悉了 Shell 之后笆制,都應(yīng)該再學(xué)習(xí) Python 語言涣达。
Python 語言的優(yōu)勢在于開發(fā)復(fù)雜的運維軟件、Web 頁面的管理工具和Web業(yè)務(wù)的開發(fā)(例如 CMDB 自動化運維平臺匆篓、跳板機寇窑、批量管理軟件 SaltStack、云計算 OpenStack 軟件)等甩骏。
Shell 腳本的優(yōu)勢在于處理偏操作系統(tǒng)底層的業(yè)務(wù),例如咨察,Linux 內(nèi)部的很多應(yīng)用(有的是應(yīng)用的一部分)都是使用 Shell 腳本開發(fā)的福青,因為有 1000 多個 Linux 系統(tǒng)命令為它作支撐,特別是 Linux 正則表達式以及三劍客 grep无午、awk媒役、sed 等命令。
對于一些常見的系統(tǒng)腳本宪迟,使用 Shell 更符合 Linux 運維簡單酣衷、易用、高效的三大原則次泽。例如鸥诽,讓軟件一鍵自動化安裝商玫、優(yōu)化,監(jiān)控報警腳本牡借,軟件啟動腳本拳昌,日志分析腳本等钠龙。
三炬藤,幾種常見的 Shell
Linux 是一個開源的操作系統(tǒng),由分布在世界各地的多個組織機構(gòu)或個人共同開發(fā)完成碴里,每個組織結(jié)構(gòu)或個人負(fù)責(zé)一部分功能沈矿,最后組合在一起,就構(gòu)成了今天的 Linux咬腋。
不同的組織機構(gòu)為了發(fā)展自己的 Linux 分支可能會開發(fā)出功能類似的軟件羹膳,它們各有優(yōu)缺點,用戶可以自由選擇根竿。Shell 就是這樣的一款軟件陵像,不同的組織機構(gòu)開發(fā)了不同的 Shell,有的占用資源少寇壳,有的支持高級編程功能醒颖,有的兼容性好,有的重視用戶體驗壳炎。常見的 Shell 有 sh泞歉、bash、csh匿辩、tcsh腰耙、ash 等。
sh 的全稱是 Bourne shell铲球,由 AT&T 公司的 Steve Bourne開發(fā)沟优,為了紀(jì)念他,就用他的名字命名了睬辐。sh 是 UNIX 上的標(biāo)準(zhǔn) shell挠阁,很多 UNIX 版本都配有 sh。sh 是第一個流行的 Shell溯饵。在現(xiàn)代的 Linux 上侵俗,sh 已經(jīng)被 bash 代替,/bin/sh往往是指向/bin/bash的符號鏈接丰刊。
csh 的語法有點類似C語言隘谣,所以才得名為 C shell ,簡稱為 csh。
tcsh 是 csh 的增強版寻歧,加入了命令補全功能掌栅,提供了更加強大的語法支持。
ash 一個簡單的輕量級的 Shell码泛,占用資源少猾封,適合運行于低內(nèi)存環(huán)境,但是與下面講到的 bash shell 完全兼容噪珊。
bash 是 Linux 的默認(rèn) shell晌缘,保持了對 sh shell 的兼容性,針對 sh 編寫的 Shell 代碼可以不加修改地在 bash 中運行,是各種 Linux 發(fā)行版默認(rèn)配置的 shell痢站。
四磷箕,進入Shell
在 Linux 操作系統(tǒng)一般有兩種方式進入 Shell 環(huán)境。
一種進入 Shell 的方法是通過快捷鍵退出圖形界面模式阵难,進入控制臺模式岳枷,這樣一來,顯示器上只有一個簡單的帶著白色文字的“黑屏”呜叫,就像圖形界面出現(xiàn)之前的樣子空繁。這種模式稱為 Linux 控制臺(Console)。
圖形界面也是一個程序怀偷,會占用CPU時間和內(nèi)存空間家厌,當(dāng) Linux 作為服務(wù)器系統(tǒng)時播玖,安裝調(diào)試完畢后椎工,應(yīng)該讓 Linux 運行在控制臺模式下,以節(jié)省服務(wù)器資源蜀踏。正是由于這個原因维蒙,很多服務(wù)器甚至不安裝圖形界面程序,管理員只能使用命令來完成各項操作果覆。
另外一種方法是使用 Linux 桌面環(huán)境中的終端模擬包(Terminal emulation package)颅痊,也就是我們常說的終端(Terminal),這樣在圖形桌面中就可以使用 Shell局待。
進入 Shell 環(huán)境后斑响,便可以看到 Shell 提示符,對于普通用戶钳榨,Base shell 默認(rèn)的提示符是美元符號$舰罚;對于超級用戶(root 用戶),Bash Shell 默認(rèn)的提示符是井號#薛耻。該符號表示 Shell 等待輸入命令营罢。
不同的 Linux 發(fā)行版使用的提示符格式不同,一般是用戶名 主機名 和當(dāng)前目錄等信息拼接而成饼齿。
CentOS 默認(rèn)的提示符格式為:
[wang@localhost ~] $
OPENTHOS 默認(rèn)提示符格式為:
bash-4.4 $
root@OPENTHOS:/ #
Shell 通過PS1和PS2兩個環(huán)境變量來控制提示符格式:
- PS1 控制最外層命令行的提示符格式饲漾。
- PS2 控制第二層命令行的提示符格式蝙搔。
默認(rèn)提示符為 PS1,當(dāng)用戶輸入了如單個 “ 字符時按回車考传,Shell 認(rèn)為語句是不完整的需要附加信息補充吃型,這時提示符就會變成 PS2,直到單個 ” 字符出現(xiàn)伙菊。
[wang@localhost ~ ]$: echo "Hello Shell"
Hello Shell
[wang@localhost ~ ]$: echo "
> Hello
> Shell
>"
Hello
Shell
[wang@localhost ~ ]$:
五败玉,腳本文件的創(chuàng)建和執(zhí)行
利用文本編輯器新建一個文件,擴展為 sh(代表Shell類型的腳本镜硕,也可以是 php等运翼,不影響執(zhí)行)。
編輯文件內(nèi)容寫入一些 Shell 語句如:
#! /bin/bash
echo "Hello Shell"
“#!” 是一個約定的標(biāo)記兴枯,它告訴系統(tǒng)這個腳本需要什么解釋器來執(zhí)行血淌,即使用哪一種Shell。
運行Shell腳本有兩種方法财剖。
1 作為可執(zhí)行程序
將上面的代碼保存為test.sh悠夯,并 cd 到相應(yīng)目錄:
chmod +x ./test.sh #使腳本具有執(zhí)行權(quán)限
./test.sh #執(zhí)行腳本
注意,一定要寫成./test.sh躺坟,而不是test.sh沦补。運行其它二進制的程序也一樣,直接寫test.sh咪橙,linux系統(tǒng)會去PATH里尋找有沒有叫test.sh的夕膀,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里美侦,你的當(dāng)前目錄通常不在PATH里产舞,所以寫成test.sh是會找不到命令的,要用./test.sh告訴系統(tǒng)說菠剩,就在當(dāng)前目錄找易猫。
通過這種方式運行bash腳本,第一行一定要寫對具壮,好讓系統(tǒng)查找到正確的解釋器准颓。
2 作為解釋器參數(shù)
這種運行方式是,直接運行解釋器棺妓,其參數(shù)就是shell腳本的文件名攘已,如:
/bin/sh test.sh
/bin/php test.php
這種方式運行的腳本,不需要在第一行指定解釋器信息涧郊,寫了也沒用贯被。
六,Shell 變量
在 Bash shell 中,每一個變量的值都是字符串彤灶,無論給變量賦值時有沒有使用引號看幼,值都會以字符串的形式存儲。這意味著幌陕,Bash shell 在默認(rèn)情況下不會區(qū)分變量類型诵姜。
定義和變量
Shell 支持以下三種定義變量的方式:
variable=value
variable='value'
variable="value"
如果 value 不包含任何空白符(例如空格、Tab縮進等)搏熄,那么可以不使用引號棚唆。
注意,賦值號的周圍不能有空格.
以單引號' '包圍 value 時心例,變量保存的是 value 直觀表面的字符串宵凌;
以雙引號" "包圍 value 時,變量保存的是將 value 內(nèi)的命令或變量解析替換之后的結(jié)果止后。
#! /bin/bash
log="log std..."
var1='${log} yes'
var2="${log} yes"
echo ${var1}
echo ${var2}
輸出結(jié)果分別為:
${log} yes
log std... yes
其中瞎惫,$ 符號表示引用變量,花括號{}可以幫助解釋器識別變量的邊界译株,最好一直都加上{}來規(guī)范習(xí)慣瓜喇。
類似的還有 $() 表示輸出括號內(nèi)的命令的執(zhí)行結(jié)果。
例如:
#! /bin/bash
var=$(ls ~)
echo ${var}
變量 var 的值為命令 ls ~ 的執(zhí)行結(jié)果歉糜,然后 echo 引用變量 var 的值進行輸出乘寒。
變量類型
運行shell時,會同時存在三種變量:
- 局部變量
局部變量在腳本或命令中定義匪补,僅在當(dāng)前shell實例中有效伞辛,其他shell啟動的程序不能訪問局部變量。 - 環(huán)境變量
所有的程序叉袍,包括shell啟動的程序始锚,都能訪問環(huán)境變量刽酱,有些程序需要環(huán)境變量來保證其正常運行喳逛。必要的時候shell腳本也可以定義環(huán)境變量。 - shell變量
shell變量是由shell程序設(shè)置的特殊變量棵里。shell變量中有一部分是環(huán)境變量润文,有一部分是局部變量,這些變量保證了shell的正常運行殿怜。