1. 什么是Shell腳本
shell腳本并不能作為正式的編程語言,因為它是在linux的shell中運行的,所以稱為shell腳本。事實上,shell腳本就是一些命令的集合。
假如完成某個需求需要一口氣輸入10條命令,對于簡單的命令,我們可以直接在shell窗口中輸入,但如果是比較長且復雜的命令,一次一次敲就會顯得很麻煩。我們可以把這10條命令都記錄到一個文檔中,然后去調(diào)用文檔中的命令,這樣就能一步操作完成,以后再遇到這個需求的時候也只需要調(diào)用這個文檔就行了,這個文檔就是shell腳本,只是這個文檔有它特殊的格式。
shell腳本能幫我們很方便地管理服務(wù)器,我們可以指定一個任務(wù)計劃,定時去執(zhí)行某個shell腳本以滿足需求。在正式編寫shell腳本之前,建議將所有自定義的腳本放到 /usr/local/sbin/ 目錄下,一是可以更好地管理文檔,二是方便后面的維護。
2. shell腳本的創(chuàng)建和執(zhí)行
下面來編寫第一個腳本:
# cd /usr/local/sbin/
# vim first.sh #寫入下面內(nèi)容
#!/bin/bash
## This is my first shell script.
## Writen by lzx 2018-7-27
date
echo "Hello World!"
shell腳本通常都以.sh作為后綴名,不是說不加.sh的腳本不能運行,只是大家的習慣,這樣也方便辨識。
上面,第一行要以#!/bin/bash開頭,表示該文件使用的是bash語法,不設(shè)置該行也可以執(zhí)行,但不符合規(guī)范。
#表示注釋,后面跟一些該腳本的相關(guān)注釋內(nèi)容,以及作者、創(chuàng)建日期或版本等。注釋可以省略,但不建議省略,因為我們的記憶力有限,沒有注釋我們自己都不知道自己寫的腳本是用來干什么的、是什么時候?qū)懙?。建議從一開始就要養(yǎng)成寫腳本的良好習慣,方便自己也方便他人。
下面來執(zhí)行上面的腳本:
# sh first.sh #用sh命令來執(zhí)行
2018年 07月 27日 星期五 09:42:54 CST
Hello World!
還有一種執(zhí)行方式:
# ./first.sh #./表示當前目錄
-bash: ./first.sh: 權(quán)限不夠
# chmod +x first.sh #給執(zhí)行權(quán)限
# ./first.sh
2018年 07月 27日 星期五 09:44:09 CST
Hello World!
使用上面方法來執(zhí)行shell腳本的前提是腳本本身有執(zhí)行權(quán)限,所以需要給腳本加一個x權(quán)限。
另外,使用sh命令來執(zhí)行腳本時,可以加-x選項來查看腳本的執(zhí)行過程:
# sh -x first.sh
+ date
2018年 07月 27日 星期五 09:49:22 CST
+ echo 'Hello World!'
Hello World!
2.1 命令date
上面有使用date命令,這個命令在shell腳本中使用很頻繁,最常見的幾個用法如下:
date +%Y :表示以四位數(shù)字格式打印年份
date +%y :表示以兩位數(shù)字格式打印年份
date +%m :表示月份
date +%d :表示日期
date +%H :表示小時
date +%M :表示分鐘
date +%S :表示秒
date +%w :表示星期,0~6,0表示星期天
# date #顯示當前時間
2019年 10月 25日 星期五 09:56:08 CST
# date +"%Y-%m-%d %H:%M:%S" #數(shù)字格式顯示
2019-10-25 10:02:08
參數(shù)說明:
-d datestr : 顯示 datestr 中所設(shè)定的時間 (非系統(tǒng)時間)
–help : 顯示輔助訊息
-s datestr : 將系統(tǒng)時間設(shè)為 datestr 中所設(shè)定的時間
-u : 顯示目前的格林威治時間
–version : 顯示版本編號
有時,在腳本中會用到一天前的日期:
# date -d "-1 day" +%d # -d設(shè)定時間,-1 day 表示當前日期前1天,可以以此類推
23
或者一小時前:
# date -d "-1 hour" +%H # -1 hour表示當前時間前1小時,可以以此類推
09
或者一分鐘前:
# date -d "-1 min" +%M # -1 min表示當前時間前1分鐘,可以以此類推
09
3. Shell腳本中的變量
shell腳本中的變量可以是一個數(shù)值、一個命令或者一個路徑。定義變量的格式為:變量名=變量的值,在腳本中引用變量時需要加上符號$。
下面編寫一個與變量有關(guān)的腳本:
# vim variable.sh #寫入下面內(nèi)容
#!/bin/bash
## In this script we will use variables.
## Writen by lzx 2018-7-27
d=`date +%H:%M:%S` #反引號的作用是將引號內(nèi)的字符串當成shell命令執(zhí)行,返回命令的執(zhí)行結(jié)果
echo "The script begin at $d."
echo "Now we'll sleep 2 seconds."
sleep 2
d1=`date +%H:%M:%S`
echo "The script end at $d1."
上面d和d1作為變量出現(xiàn)。
執(zhí)行上面腳本,查看執(zhí)行結(jié)果:
# sh variable.sh
The script begin at 10:27:22.
Now we'll sleep 2 seconds.
The script end at 10:27:24.
3.1 數(shù)字運算
在腳本中進行數(shù)字運算,也會用到變量。
下面再自定義一個腳本:
# vim sum.sh #寫入下面內(nèi)容
#! /bin/bash
## For get the sum of two numbers.
## Writen by lzx 2018-7-27
a=1
b=2
sum=$[$a+$b]
echo "$a+$b=$sum"
數(shù)學計算要用[]括起來,并且前面要加上符號$。
# sh sum.sh
1+2=3
3.2 與用戶交互
自定義一個腳本:
# vim read.sh
#!/bin/bash
## Using 'read' in shell script.
## Writen by lzx 2018-7-27
read -p "Please input a number:" x
read -p "Please input another number:" y
sum=$[$x+$y]
echo "The sum of two numbers is:$sum"
read命令用于和用戶交互,它把用戶輸入的字符串作為變量值
# sh read.sh
Please input a number:5
Please input another number:11
The sum of two numbers is:16
加上 -x選項查看執(zhí)行過程:
# sh -x read.sh
+ read -p 'Please input a number:' x
Please input a number:5
+ read -p 'Please input another number:' y
Please input another number:11
+ sum=16
+ echo 'The sum of two numbers is:16'
The sum of two numbers is:16
3.3 shell腳本預設(shè)變量
我們之前有使用過類似/etc/init.d/iptables restart這樣的命令,前面的/etc/init.d/iptables文件其實就是一個shell腳本。那為什么后面可以跟一個restart字符串呢?這就涉及到了shell腳本的預設(shè)變量。
實際上,shell腳本在執(zhí)行時,后面可以跟一個或者多個參數(shù)。
下面自定義一個腳本:
# vim option.sh #寫入下面內(nèi)容
#!/bin/bash
## 測試預設(shè)變量
## Writen by lzx 2018-7-27
sum=$[$1+$2]
echo "sum=$sum"
# sh option.sh #后面不加參數(shù)時,腳本會出錯
option.sh:行5: +: 語法錯誤: 期待操作數(shù) (錯誤符號是 "+")
# sh option.sh 5 11 #后面加5和11,5和11就是預設(shè)變量$1和$2
sum=16
2表示腳本的第二個參數(shù),以此類推。
一個腳本的預設(shè)變量數(shù)量是沒有限制的,另外還有$0,它表示腳本本身的名字。
# vim option1.sh #寫入下面內(nèi)容
#!/bin/bash
echo "$1 $2 $0"
# sh option1.sh 1 2
1 2 option1.sh #可以看到,顯示出$0為option1.sh,即腳本名字
4. Shell腳本中的邏輯判斷
如果你學過其它編程語言,那么就不會對if感到陌生。在shell腳本中,我們同樣可以使用if邏輯判斷。
4.1 不帶else
具體格式如下:
if 判斷語句;then
command
fi
下面自定義一個腳本:
# vim if1.sh #寫入下面內(nèi)容
#!/bin/bash
read -p "Please input your score: " a
if ((a<60));then
echo "You didn't pass the exam."
fi
上面出現(xiàn)了((a<60))這樣的形式,(( ))這是shell腳本特有的格式,只用一個小括號或不用括號都會報錯,要記住這個格式。
查看上面腳本的執(zhí)行結(jié)果:
# sh if1.sh
Please input your score: 90 #沒有設(shè)置else條件,所以沒有結(jié)果
# sh if1.sh
Please input your score: 50
You didn't pass the exam.
4.2 帶有else
具體格式如下:
if 判斷語句
then
command
else
command
fi
下面做if1.sh腳本做修改:
# vim if1.sh #修改為下面內(nèi)容
#!/bin/bash
read -p "Please input your score: " a
if ((a<60));then
echo "You didn't pass the exam."
else
echo "Good!You passed the exam."
fi
執(zhí)行上面腳本:
# sh if1.sh
Please input your score: 90
Good!You passed the exam. #設(shè)置了else條件之后,這里返回了結(jié)果
# sh if1.sh
Please input your score: 50
You didn't pass the exam.
4.3 帶有elif
具體格式如下:
if 判斷語句1;then
command
elif 判斷語句2;then
command
else
command
fi
下面自定義一個腳本:
# vim if2.sh #寫入下面內(nèi)容
#!/bin/bash
read -p "Please input you score: " a
if ((a<60));then
echo "You didn't pass the exam."
elif ((a>=60)) && ((a<90));then # elif相對if,再做一次判斷
echo "Good!You passed the exam."
else
echo "Very good!Your score is very high."
fi
上面的 &&表示“并且”,另外還有||表示“或者”。
執(zhí)行上面腳本:
# sh if2.sh
Please input you score: 40
You didn't pass the exam.
# sh if2.sh
Please input you score: 85
Good!You passed the exam.
# sh if2.sh
Please input you score: 95
Very good!Your score is very high.
判斷數(shù)值大小除了可以使用(( ))的形式外,還可以使用[],但不能使用>、<、=這樣的符號了,要使用-lt(小于)、-gt(大于)、-le(小于或等于)、-ge(大于或等于)、-eq(等于)、-ne(不等于)。
示例如下:
# a=10; if [ $a -lt 1 ] || [ $a -gt 5 ]; then echo ok; fi #注意[]空格,否則會有語法錯誤
ok
# a=5; if [ $a -lt 10 ] || [ $a -gt 1 ]; then echo ok; fi
ok
4.4 和文檔相關(guān)的判斷
shell腳本中if還經(jīng)常用于判斷文檔的屬性,比如判斷是普通文件還是目錄,判斷文件是否可讀、寫、執(zhí)行權(quán)限等。
if 常用的選項有以下幾個:
-e :判斷文件或目錄是否存在
-d :判斷是不是目錄以及是否存在
-f :判斷是不是普通文件以及是否存在
-r :判斷是否有讀權(quán)限
-w :判斷是否有寫權(quán)限
-x :判斷是否有執(zhí)行權(quán)限
具體格式如下:
if [ -e filename ]
then
command
fi
示例如下:
# if [ -d /home/ ]; then echo ok; fi
ok
# if [ -f /home/ ]; then echo ok; fi
/home/是目錄而非文件,所以在判斷它是否為文件時并不會顯示ok。
# if [ -f /root/test.txt ]; then echo ok; fi
ok
# if [ -r /root/test.txt ]; then echo ok; fi
ok
# if [ -w /root/test.txt ]; then echo ok; fi
ok
# if [ -x /root/test.txt ]; then echo ok; fi
# if [ -e /root/test123.txt ]; then echo ok; fi
4.5 case邏輯判斷
在shell腳本中,除了使用if來判斷邏輯外,還可以使用case。
具體格式如下:
case 變量 in
value1)
command
;;
value2)
command
;;
value3)
command
;;
*)
command
;;
esac
上面的結(jié)構(gòu)中,不限制value的個數(shù),*代表其它任意值。
下面自定義一個腳本:
# vim case.sh
#!/bin/bash
read -p "Input a number: " n
a=$[n%2]
case $a in
1)
echo "The number is odd." # odd:奇數(shù)
;;
0)
echo "The number is even." # even:偶數(shù)
;;
*)
echo "It's not a number!"
esac
腳本中的$a的值為1或0,執(zhí)行結(jié)果如下:
# sh case.sh
Input a number: 100
The number is even.
# sh case.sh
Input a number: 13
The number is odd.
case腳本常用于編寫系統(tǒng)服務(wù)的啟動腳本。
5. Shell腳本中的循環(huán)
shell腳本算是一門簡易的編程語言了,腳本中的循環(huán)也是不能缺少的。常用的循環(huán)有for循環(huán)和while循環(huán)。
5.1 for循環(huán)
for循環(huán)結(jié)構(gòu)是在日常運維工作中使用很頻繁的循環(huán)結(jié)構(gòu)。
具體格式如下:
for 變量名 in 循環(huán)的條件
do
command
done
下面自定義一個腳本:
# vim for.sh #寫入下面內(nèi)容
#!/bin/bash
for i in `seq 1 5`; do # seq 1 5 表示從1到5的一個序列
echo $i
done
查看執(zhí)行結(jié)果:
# sh for.sh
1
2
3
4
5
上面,循環(huán)的條件是引用系統(tǒng)命令的執(zhí)行結(jié)果seq 1 5,但必須用反引號括起來。
示例如下:
# for file in `ls`; do echo $file; done
case.sh
check_ng.sh
first.sh
for.sh
if1.sh
if2.sh
option1.sh
option.sh
read.sh
sum.sh
variable.sh
另外循環(huán)的條件還可以是一組字符或者數(shù)字(用一個或多個空格隔開),也可以是一條命令的執(zhí)行結(jié)果。
示例如下:
# for i in 1 2 3 a b c; do echo $i; done
1
2
3
a
b
c
5.2 while循環(huán)
日常運維工作中,也會經(jīng)常用while循環(huán)來編寫死循環(huán)的腳本,用于監(jiān)控某項服務(wù)。
具體格式如下:
while 條件
do
command
done
下面自定義一個腳本:
#!/bin/bash
a=6
while [ $a -ge 1]
do
echo $a
a=$[$a-1]
done
查看執(zhí)行結(jié)果:
# sh while.sh
6
5
4
3
2
1
另外,可以用一個冒號:代替循環(huán)條件,這樣就可以做到死循環(huán)。
6. Shell腳本中的函數(shù)
shell腳本中的函數(shù)就是先把一段代碼整理到一個小單元中,并給這個小單元命名,當用到這段代碼時,直接調(diào)用這個小單元的名字即可。
下面自定義一個腳本:
# vim func.sh
#!/bin/bash
function sum()
{
sum=$[$1+$2]
echo $sum
}
sum $1 $2 #預設(shè)變量$1 $2
查看執(zhí)行結(jié)果:
# sh func.sh 1 2
3
上面func.sh中的sum()為自定義的函數(shù)。
在shell腳本中函數(shù)的格式如下:
function 函數(shù)名()
{
command1
command2
}
需要注意的是,在shell腳本中,被調(diào)用的函數(shù)一定要寫在最前面,不能出現(xiàn)在中間或最后。因為函數(shù)是要被調(diào)用的,如果還沒有出現(xiàn)就被調(diào)用,那當然會出錯。
7. Shell腳本中的中斷和繼續(xù)
在shell腳本循環(huán)的過程中,我們難免會遇到一些特殊需求,比如當循環(huán)到某個地方時需要做一些事情,這時候很有可能需要退出循環(huán),或者跳過本次循環(huán)。
7.1 break
break用在循環(huán)中,不管是for或者while都可以。在腳本中使用它,表示退出本層循環(huán)。之所以說層,是因為有時我們會用到嵌套循環(huán),大循環(huán)里面還有小循環(huán),而break僅僅是退出那一層循環(huán),它的上層循環(huán)不受影響。
下面自定義一個腳本:
# vim break.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 3 ]
then
break
fi
done
echo aaa
查看執(zhí)行結(jié)果:
# sh break.sh
1
2
3
aaa
上面腳本中,當i=3時,會跳出循環(huán),后面的4和5不再執(zhí)行,但上層的循環(huán)仍在繼續(xù)。
7.2 continue
continue也是使用在循環(huán)中的,但和break不同,當在shell腳本中遇到continue時,結(jié)束的不是整個循環(huán),而是本次循環(huán)(不退出本層循環(huán),只是結(jié)束這一次循環(huán))。
下面自定義一個腳本:
# vim continue.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 3 ]
then
continue
fi
echo $i
done
查看執(zhí)行結(jié)果:
# sh continue.sh
1
1
2
2
3
4
4
5
5
當i=3時,因為有continue,結(jié)束本次循環(huán),continue后面的語句不再執(zhí)行,但是后面的循環(huán)不受影響。
7.3 exit
還有一個和break、continue類似的用法,就是exit,它作用的范圍更大,直接退出整個shell腳本。
下面修改continue.sh:
# vim continue.sh #修改為下面內(nèi)容
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 3 ]
then
exit
fi
echo $i
done
echo aaa
查看執(zhí)行結(jié)果:
# sh continue.sh
1
1
2
2
3
這個結(jié)果和continue相比,明顯exit在i=3時,就直接退出了整個腳本。
原文作者:最愛喝酸奶
原文地址:https://blog.csdn.net/miss1181248983/article/details/81278937
推薦
大廠筆試內(nèi)容集合(內(nèi)有詳細解析) 持續(xù)更新中....
文末
歡迎關(guān)注個人微信公眾號:Coder編程
歡迎關(guān)注Coder編程公眾號,主要分享數(shù)據(jù)結(jié)構(gòu)與算法、Java相關(guān)知識體系、框架知識及原理、Spring全家桶、微服務(wù)項目實戰(zhàn)、DevOps實踐之路、每日一篇互聯(lián)網(wǎng)大廠面試或筆試題以及PMP項目管理知識等。更多精彩內(nèi)容正在路上~
新建了一個qq群:315211365,歡迎大家進群交流一起學習。謝謝了!也可以介紹給身邊有需要的朋友。
文章收錄至
Github: https://github.com/CoderMerlin/coder-programming
Gitee: https://gitee.com/573059382/coder-programming
歡迎關(guān)注并star~
微信公眾號