shell程式設計是從事linux運維同學的必備技能,靈活運用shell 指令碼可以大大減少日常重複性的維護工作,也是自動化運維的早期體現形式。在日常工作中,經常有運維同學反映shell難學,語法難記憶。其實在我看來,學習任何技術都是要結合場景進行實踐練習的。前期可以通過快速入門基礎語法知識,結合一定的運維場景編寫一些簡單的shell指令碼,激發自己的學習興趣,然後再不斷積累shell的高階語法要點。
本系列文章會以shell程式設計 101 作為shell程式設計入門篇,介紹一些基礎的語法知識,使讀者學完後具備編寫簡單shell 指令碼的能力,後續shell高階語法點以單獨專題的方式呈現,讓讀者可以從整體把握shell程式設計,形成框架,然後不斷的向裡填充知識要點,不會因為上來就闡述大量的語法知識而感到枯燥。
let』s get started.
1. 變數
1.1 變數宣告
格式:
變數名=值
注意:變數名是由數字、字母以及下劃線組成,但不能以數字開頭,同時定義的變數名不能是shell自身定義的關鍵字。
例子:a=1
name=『alice』
ip=『1.1.1.1』
1.2 使用變數:
#/bin/bash
#致敬經典
words=
"hello,world"
echo
$
在shell程式設計中,大多數的shell命令在結合變數使用都是遵循以下格式的:
command [-option] $
這裡需要注意,如果是對變數的賦值,要直接對變數名進行賦值,不需要用${}這樣的格式,因為並沒有實際使用變數,這裡只是定義或賦值變數。
例子:words=「move on」 (正確)
$=「move on」 (錯誤)
應用案例:
#/bin/bash
#ping ip address
ip="114.114.114.114"
ping -c 3 $
可以看到,通過使用變數,我們無需直接修改ping命令中的ip位址,僅需在ip變數定義處統一進行修改。但這裡有個問題,如果想要獲得ping的結果並且做出相應的動作,應該怎麼做呢?我們在第二部分選擇結構中給出答案。
2 選擇結構
1 if-else
格式:
if 條件
then
語句1else
語句2fi
說明:如果條件成立,則執行語句1,否則執行語句2
例子:
#/bin/bash
a=1b=2if[
$ -gt $
]then
echo
"$ > $"
else
echo
"$< $"
fi
結果:
1 < 2
這裡是通過test命令([ ] 是簡寫),結合if-else 對兩個變數進行大小判斷,並作出相應的動作響應。這裡不用糾結test命令用法,後面會單獨作專題進行詳細說明。
如果需要通過多個分支進行判斷,shell也是支援的。
if 條件
then
語句1elif 條件
then
語句2elif 條件
then
語句3…
else
語句4fi
應用案例
1 根據第一部分的場景,要求上一定的拓展,ping生產環境的機器,並反饋ping結果。
#/bin/bash
#define ip address
ip="114.114.114.114"
#ping ip address
ping -c 1 $
>/dev/null 2>
&1#check ping resultif[
$?== 0 ]
then
echo
"$ is alive."
else
echo
"$ is unreachable."
fi
這裡通過自定義ip位址,並根據ping的結果,列印出對應的結果。
此時,在第乙個應用案例中提到的根據ping結果,做出相應的動作的問題得到了解決。如果我們再進一步貼近實際場景,生產環境肯定不止一台主機,那麼如何ping多台主機,並統計ping主機的結果呢?讓我們帶著疑問,走進第三部分:迴圈
3.迴圈結構
1. 經典for迴圈
格式:
for((exp1; exp2; exp3))
do語句
done
例子:
#!/bin/bash
sum=0
for((i=
1; i<=
100; i++
))do
((sum +
= i))
done
echo
"the sum result is: $sum"
這裡我們結合例子來說,i=1是作為初始化的變數,賦值為1, i<=100是為了控制迴圈的次數,i++是對i進行自增長。整個程式的解讀為將sum賦值為0, 然後執行for迴圈,第一次迴圈i=1,此時判斷i<=100,t條件成立,然後執行語句塊裡面的內容,也就是sum+i的值最後再賦值給sum.語句塊執行完後執行i++, 此時i等於2,且也小於100,然後第二次執行語句塊sum+i,然後賦值給sum, 然後i++,此時i等於3,且小於100,第三次執行語句塊,依次類推,直至i大於100,迴圈結束。
結果:
the sum result is: 5050
2. for in 迴圈
格式:
for 變數 in 數值列表
do語句
done
說明:每次迴圈會去數值列表中取乙個值賦給變數,然後進入迴圈體進行執行語句,直至取完全部的值,迴圈結束。
例子:乙個文字中有10條記錄,通過迴圈列印出來。
文字內容:
host1
host2
host3
host4
host5
#/bin/bash
for host in
`cat host.txt`
doecho
$done
執行結果:
host1
host2
host3
host4
host5
通過cat host.txt 獲取檔案中的內容,每次迴圈取一行的內容賦給host變數,然後進入迴圈體,通過echo命令列印出host變數的值,然後取下一行的值繼續賦給host變數,以此類推。
應用案例:
我們對第二部分的應用場景加以拓展,此時生產環境有10臺主機,希望通過指令碼探測主機存活情況,並統計探測結果。
#/bin/bash
for ip in
`cat iplist.txt`
doping -c 1 $
>/dev/null 2>
&1 if[$?
== 0 ]
then
echo
"$ is alive."
else
echo
"$ is unreachable."
fidone
結果:
192.168.78.191 is unreachable.
192.168.87.192 is alive.
192.168.87.193 is unreachable.
192.168.87.194 is unreachable.
192.168.87.195 is unreachable.
4.一些特殊用法的說明
在前面的指令碼中涉及到一些特殊的shell用法,在這裡統一做乙個補充說明:
1 反引號用法
for ip in
`cat iplist.txt`
這裡的反引號是獲取cat iplist.txt 命令執行後的結果。也可以通過$(cat iplist.txt) 達到同樣的效果。
2 $?是什麼?
$?是用於獲取上乙個命令的退出狀態,一般大部分命令執行成功返回0,失敗返回1.
3 這裡 >/dev/null 2>&1 是什麼意思?
這裡的》是重定向符,用於將輸出內容重定向至/dev/null檔案(可以理解為乙個黑洞,內容定向寫入到這個檔案會被永遠丟棄)。 2>&1 標識將產生的錯誤資訊重定向至輸出內容所定向的檔案,也是就/dev/null。
希望對大家有所幫助!
tony
又見101個shell指令碼
很久沒更新了,很久沒看指令碼了 想想應該繼續看指令碼了 bin sh a version of fmt,using nroff.adds two useful flags w x for line width and h to enable hyphenation for better fills....
C 程式設計規範101條
第1條 在高警告級別乾淨利落地進行編譯 第2條 使用自動構建系統 第3條 使用版本控制系統 第4條 做 審查 設計風格 程式設計風格 容器1 類 函式 列舉的名稱形如likethis,每個單詞首字母都大寫。2 變數的名字如likethis,第二個單詞首字母大寫 3 類中私有成員變數名形如liketh...
Shell程式設計 shell特性
linux會預設記錄1000條歷史記錄,可通過 echo histsize 檢視,如果講histsize更改為2000,那麼會預設儲存2000條。1000條記錄儲存在家目錄的 bash history 中,僅當使用者正常退出當前shell時,當前shell中執行的命令才會儲存到 bash histo...