Shell程式設計 101

2021-10-08 13:56:25 字數 4553 閱讀 7817

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...