Shell腳本基礎(轉載)

原網頁地址:https://www.cnblogs.com/zhang-jun-jie/p/9266858.html

shell腳本的基本結構以及如何執行

Shell腳本通常都是以.sh 爲後綴名的,這個並不是說不帶.sh這個腳本就不能執行,只是大家的一個習慣而已。所以,以後你發現了.sh爲後綴的文件那麼它一定會是一個shell腳本了。test.sh中第一行一定是 “#! /bin/bash” 它代表的意思是,該文件使用的是bash語法。如果不設置該行,那麼你的shell腳本就不能被執行。’#’表示註釋,在前面講過的。後面跟一些該腳本的相關注釋內容以及作者和創建日期或者版本等等。當然這些註釋並非必須的,如果你懶的很,可以省略掉,但是筆者不建議省略。因爲隨着你工作時間的增加,你寫的shell腳本也會越來越多,如果有一天你回頭查看你寫的某個腳本時,很有可能忘記該腳本是用來幹什麼的以及什麼時候寫的。所以寫上註釋是有必要的。另外系統管理員並非你一個,如果是其他管理員查看你的腳本,他看不懂豈不是很鬱悶。該腳本再往下面則爲要運行的命令了。

Shell腳本的執行很簡單,直接”sh filename “ 即可,另外你還可以這樣執行

默認我們用vim編輯的文檔是不帶有執行權限的,所以需要加一個執行權限,那樣就可以直接使用’./filename’ 執行這個腳本了。另外使用sh命令去執行一個shell腳本的時候是可以加-x選項來查看這個腳本執行過程的,這樣有利於我們調試這個腳本哪裏出了問題。

該shell腳本中用到了’date’這個命令,它的作用就是用來打印當前系統的時間。其實在shell腳本中date使用率非常高。有幾個選項筆者常常在shell腳本中用到:

%Y表示年,%m表示月,%d表示日期,%H表示小時,%M表示分鐘,%S表示秒

注意%y和%Y的區別。

-d 選項也是經常要用到的,它可以打印n天前或者n天后的日期,當然也可以打印n個月/年前或者後的日期。

另外星期幾也是常用的

【shell腳本中的變量

在shell腳本中使用變量顯得我們的腳本更加專業更像是一門語言,開個玩笑,變量的作用當然不是爲了專業。如果你寫了一個長達1000行的shell腳本,並且腳本中出現了某一個命令或者路徑幾百次。突然你覺得路徑不對想換一下,那豈不是要更改幾百次?你固然可以使用批量替換的命令,但是也是很麻煩,並且腳本顯得臃腫了很多。變量的作用就是用來解決這個問題的。

在test2.sh中使用到了反引號,你是否還記得它的作用?’d’和’d1’在腳本中作爲變量出現,定義變量的格式爲 “變量名=變量的值”。當在腳本中引用變量時需要加上’$’符號,這跟前面講的在shell中自定義變量是一致的。下面看看腳本執行結果吧。

下面我們用shell計算兩個數的和。

數學計算要用’[ ]’括起來並且外頭要帶一個’$’。腳本結果爲:

Shell腳本還可以和用戶交互。

這就用到了read命令了,它可以從標準輸入獲得變量的值,後跟變量名。”read x”表示x變量的值需要用戶通過鍵盤輸入得到。腳本執行過程如下:

我們不妨加上-x選項再來看看這個執行過程:

在test4.sh中還有更加簡潔的方式。

read -p 選項類似echo的作用。執行如下:

你有沒有用過這樣的命令”/etc/init.d/iptables restart “ 前面的/etc/init.d/iptables 文件其實就是一個shell腳本,爲什麼後面可以跟一個”restart”? 這裏就涉及到了shell腳本的預設變量。實際上,shell腳本在執行的時候後邊是可以跟變量的,而且還可以跟多個。不妨筆者寫一個腳本,你就會明白了。

執行過程如下:

在腳本中,你會不會奇怪,哪裏來的$1和$2,這其實就是shell腳本的預設變量,其中$1的值就是在執行的時候輸入的1,而$2的值就是執行的時候輸入的$2,當然一個shell腳本的預設變量是沒有限制的,這回你明白了吧。另外還有一個$0,不過它代表的是腳本本身的名字。不妨把腳本修改一下。

執行結果想必你也猜到了吧。

【shell腳本中的邏輯判斷

如果你學過C或者其他語言,相信你不會對if 陌生,在shell腳本中我們同樣可以使用if邏輯判斷。在shell中if判斷的基本語法爲:

1)不帶else

if 判斷語句; then

command

fi

在if1.sh中出現了 ((a<60))這樣的形式,這是shell腳本中特有的格式,用一個小括號或者不用都會報錯,請記住這個格式,即可。執行結果爲:

2)帶有else

if 判斷語句 ; then

command

else

command

fi

執行結果爲:

3)帶有elif

if 判斷語句一 ; then

command

elif 判斷語句二; then

command

else

command

fi

這裏的 && 表示“並且”的意思,當然你也可以使用 || 表示“或者”,執行結果:

以上只是簡單的介紹了if語句的結構。在判斷數值大小除了可以用”(( ))”的形式外,還可以使用”[ ]”。但是就不能使用>, < , = 這樣的符號了,要使用 -lt (小於),-gt (大於),-le (小於等於),-ge (大於等於),-eq (等於),-ne (不等於)。

再看看if中使用 && 和 ||的情況。

shell 腳本中if還經常判斷關於檔案屬性,比如判斷是普通文件還是目錄,判斷文件是否有讀寫執行權限等。常用的也就幾個選項:

-e :判斷文件或目錄是否存在

-d :判斷是不是目錄,並是否存在

-f :判斷是否是普通文件,並存在

-r :判斷文檔是否有讀權限

-w :判斷是否有寫權限

-x :判斷是否可執行

使用if判斷時,具體格式爲: if [ -e filename ] ; then

在shell 腳本中,除了用if來判斷邏輯外,還有一種常用的方式,那就是case了。具體格式爲:

case 變量 in

value1)

command

;;

value2)

command

;;

value3)

command

;;

*)

command

;;

esac

上面的結構中,不限制value的個數,*則代表除了上面的value外的其他值。下面筆者寫一個判斷輸入數值是奇數或者偶數的腳本。

$a 的值或爲1或爲0,執行結果爲:

也可以看一下執行過程:

case腳本常用於編寫系統服務的啓動腳本,例如/etc/init.d/iptables中就用到了,你不妨去查看一下。

【shell腳本中的循環

Shell腳本中也算是一門簡易的編程語言了,當然循環是不能缺少的。常用到的循環有for循環和while循環。下面就分別介紹一下兩種循環的結構。

腳本中的seq 1 5 表示從1到5的一個序列。你可以直接運行這個命令試下。腳本執行結果爲:

通過這個腳本就可以看到for循環的基本結構:

for 變量名 in 循環的條件; do

command

done

循環的條件那一部分也可以寫成這樣的形式,中間用空格隔開即可。你也可以試試,for i in `ls`; do echo $i; done 和 for i in `cat test.txt`; do echo $i; done

再來看看這個while循環,基本格式爲:

while 條件; do

command

done

腳本的執行結果爲:

另外你可以把循環條件忽略掉,筆者常常這樣寫監控腳本。

while :; do

command

done

【shell腳本中的函數

如果你學過開發,肯定知道函數的作用。如果你是剛剛接觸到這個概念的話,也沒有關係,其實很好理解的。函數就是把一段代碼整理到了一個小單元中,並給這個小單元起一個名字,當用到這段代碼時直接調用這個小單元的名字即可。有時候腳本中的某段代總是重複使用,如果寫成函數,每次用到時直接用函數名代替即可,這樣就節省了時間還節省了空間。

fun.sh 中的sum() 爲自定義的函數,在shell腳本中要用

function 函數名() {

command

}

這樣的格式去定義函數。

上個腳本執行過程如下:

有一點筆者要提醒你一下,在shell腳本中,函數一定要寫在最前面,不能出現在中間或者最後,因爲函數是要被調用的,如果還沒有出現就被調用,肯定是會出錯的。

Shell腳本大體上就介紹這麼多了,筆者所舉的例子都是最基礎的,所以即使你把所有例子完全掌握也不代表你的shell腳本編寫能力有多麼好。所以剩下的日子裏你儘量要多練習,多寫腳本,你寫的腳本越多,你的能力就越強。希望你能夠找專門介紹shell腳本的書籍深入的去研究一下它。隨後筆者將給你留幾個shell腳本的練習題,你最好不要偷懶。

1. 編寫shell腳本,計算1-100的和;

2. 編寫shell腳本,要求輸入一個數字,然後計算出從1到輸入數字的和,要求,如果輸入的數字小於1,則重新輸入,直到輸入正確的數字爲止;

3. 編寫shell腳本,把/root/目錄下的所有目錄(只需要一級)拷貝到/tmp/目錄下;

4. 編寫shell腳本,批量建立用戶user_00, user_01, … ,user_100並且所有用戶同屬於users組;

5. 編寫shell腳本,截取文件test.log中包含關鍵詞’abc’的行中的第一列(假設分隔符爲”:”),然後把截取的數字排序(假設第一列爲數字),然後打印出重複次數超過10次的列;

6. 編寫shell腳本,判斷輸入的IP是否正確(IP的規則是,n1.n2.n3.n4,其中1<n1<255, 0<n2<255,="" 0<n3<255,="" 0<n4<255<="" span="">)。

以下爲練習題答案:

1. #! /bin/bash

sum=0

for i in `seq 1 100`; do

sum=$[$i+$sum]

done

echo $sum

2. #! /bin/bash

n=0

while [ $n -lt "1" ]; do

read -p "Please input a number, it must greater than "1":" n

done

sum=0

for i in `seq 1 $n`; do

sum=$[$i+$sum]

done

echo $sum

3. #! /bin/bash

for f in `ls /root/`; do

if [ -d $f ] ; then

cp -r $f /tmp/

fi

done

4. #! /bin/bash

groupadd users

for i in `seq 0 9`; do

useradd -g users user_0$i

done

for j in `seq 10 100`; do

useradd -g users user_$j

done

5. #! /bin/bash

awk -F':' '$0~/abc/ {print $1}' test.log >/tmp/n.txt

sort -n n.txt |uniq -c |sort -n >/tmp/n2.txt

awk '$1>10 {print $2}' /tmp/n2.txt

6. #! /bin/bash

checkip() {

if echo $1 |egrep -q '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' ; then

a=`echo $1 | awk -F. '{print $1}'`

b=`echo $1 | awk -F. '{print $2}'`

c=`echo $1 | awk -F. '{print $3}'`

d=`echo $1 | awk -F. '{print $4}'`

for n in $a $b $c $d; do

if [ $n -ge 255 ] || [ $n -le 0 ]; then

echo "the number of the IP should less than 255 and greate than 0"

return 2

fi

done

else

echo "The IP you input is something wrong, the format is like 192.168.100.1"

return 1

fi

}

rs=1

while [ $rs -gt 0 ]; do

read -p "Please input the ip:" ip

checkip $ip

rs=`echo $?`

done

echo "The IP is right!"

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章