做 Java 的肯定都接觸過 Linux 系統(tǒng),那么很多時(shí)候我們在開發(fā)的過程中都是把我們項(xiàng)目打成一個(gè)jar包,或者是war包的形式,然后通過 XFTP 上傳到我們服務(wù)器的指定目錄,然后運(yùn)行一端啟動(dòng)腳本,讓我們的項(xiàng)目變得可以訪問 就像???./sh service.sh start?
??然后啟動(dòng)我們寫好的???sh?
??的shell腳本。接下來我們就來學(xué)習(xí)一下關(guān)于 Shell 腳本是如何寫出來的。
Shell 腳本
Shell 腳本是什么?Shell是一個(gè)命令解釋器,它的作用是解釋執(zhí)行用戶輸入的命令及程序等,也就是說,我們用戶每輸入一條命令,Shell 就會(huì)相對(duì)應(yīng)的執(zhí)行一條命令。當(dāng)命令或程序語句不在命令行下執(zhí)行,而是通過一個(gè)程序文件來執(zhí)行時(shí),該程序文件就被稱為Shell腳本。
在我們的 Shell 腳本中,會(huì)有各種各樣的內(nèi)容,賦值,計(jì)算,循環(huán)等一系列的操作,接下來我們就來看看這個(gè) Shell 腳本怎么寫吧
1.查看自己當(dāng)前系統(tǒng)默認(rèn)的 Shell
??echo $SHELL?
?
輸出:/bin/bash
2.查看系統(tǒng)支持的Shell
??cat /etc/shells?
?
輸出:
/bin/sh /bin/bash /usr/bin/sh /usr/bin/bash
也就是說,我們的云服務(wù)器是支持我們在這里給他安排 Shell 腳本的
Shell 腳本怎么寫出來的
我們這時(shí)候先來安排一下???sh?
???的文件,創(chuàng)建一個(gè)文件夾,然后在其中創(chuàng)建一個(gè)???sh?
??的文件。
??mkdir /usr/local/shelltest?
?
??touch test.sh?
?
創(chuàng)建完成我們編輯一下內(nèi)容
??vim test.sh?
?
#!/bin/bash
echo "Hello World Shell"
然后我們出來運(yùn)行一下我們的 Shell 的第一個(gè)腳本
??bash test.sh?
?
出來的結(jié)果是???Hello World Shell?
?
一個(gè)及其簡單的腳本出現(xiàn)了,接下我們就分析一波我們寫了點(diǎn)啥?
??#!/bin/bash?
?
#! 是一個(gè)約定的標(biāo)記,它告訴系統(tǒng)這個(gè)腳本需要什么解釋器來執(zhí)行,即使用哪一種 Shell
我們在之前也使用了???echo $SHELL?
???來查看了自己系統(tǒng)默認(rèn)的是哪一種???sh?
??解析器,之前看到的是/bin/bash,所以我們在寫 Shell 腳本的時(shí)候,我們在開頭默認(rèn)的約定中,我們寫了這個(gè)是用 /bin/bash 來進(jìn)行解釋的,
那么我們?nèi)绾蜗裰罢{(diào)用我們的當(dāng)前目錄中的 Shell 腳本一樣去調(diào)用他呢?就像這個(gè)樣子的???./sh service.sh start?
?
1.授權(quán),
我們先不授權(quán)試一下看看能通過 ./test.sh 進(jìn)行調(diào)用么
bash: ./test.sh: Permission denied 會(huì)提示這個(gè),也就是沒有授權(quán)定義,
授權(quán)命令:chmod +x test.sh
2.執(zhí)行 ./test.sh
然后調(diào)用就能正常輸出了,就是說,在當(dāng)前的目錄下執(zhí)行這個(gè)腳本命令。
Shell 腳本的變量
- 定義變量和使用
變量命名實(shí)際上很簡單,我們先來試一下
??name=zhiyikeji?
?
這時(shí)候我們怎么使用變量呢?實(shí)際上只要在前面加上一個(gè)符號(hào)就可以 $
??echo $name?
?
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name
zhiyikeji
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo ${name}
zhiyikeji
上面的兩種寫法都是可以的,外面的大括號(hào)加和不加區(qū)別不大,可以省略,直接就??$name?
??就可以使用你定義的變量
使用括號(hào)的意義一般在于區(qū)別某些變量,比如你寫了一串的內(nèi)容,可能寫的是???echo $nameismyfriend?
??,如果連在一起,是不是有點(diǎn)尷尬,這時(shí)候就可以使用括號(hào)區(qū)別一下,??echo ${name}ismyfriend?
??不使用括號(hào)的時(shí)候,他就去找nameismyfriend這個(gè)變量了,就無法出來我們要的效果。
- 刪除自己定義的變量
??unset name?
?
這時(shí)候我們就把我們剛才定義的???name=zhiyikeji?
??這個(gè)變量給去掉了,我們可以調(diào)用一下我們的變量看是什么?
??echo $name?
?
[root@iZbp10j01t7sgfqekyefpoZ ~]# unset name
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name
這是不是就證明我們自己定義的變量已經(jīng)刪除了
- 只讀變量
那么我們需要一個(gè)關(guān)鍵字,大家肯定能想到是什么關(guān)鍵字???readonly?
?
我們先給name賦值,然后使用 readonly 設(shè)置只讀,然后再改變一下試試,
[root@iZbp10j01t7sgfqekyefpoZ ~]# name=zhiyikeji
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name
zhiyikeji
[root@iZbp10j01t7sgfqekyefpoZ ~]# readonly name
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name
zhiyikeji
[root@iZbp10j01t7sgfqekyefpoZ ~]# name=ceshi
-bash: name: readonly variable
[root@iZbp10j01t7sgfqekyefpoZ ~]#
竟然是真的,如果不設(shè)置只讀,是不是會(huì)重新可以進(jìn)行賦值,我們測試個(gè)年齡,
[root@iZbp10j01t7sgfqekyefpoZ ~]# age=10
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $age
10
[root@iZbp10j01t7sgfqekyefpoZ ~]# age=20
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $age
20
所以我們就可以肯定,readonly就是設(shè)置只讀的關(guān)鍵詞,記住了么?
那么設(shè)置只讀的變量可以刪除么?畢竟總有杠精的面試官會(huì)提問這個(gè)棘手的問題,但是,阿粉試過的所有方式好像都是不行的,阿粉就直接重啟了自己的服務(wù)器,這樣臨時(shí)的變量就不存在了!
Shell 腳本的流程控制
說真的,Shell腳本的流程控制數(shù)一般才是yyds,為什么這么說,因?yàn)槟阍趯懘蟛糠值哪_本的時(shí)候,流程控制的地方永遠(yuǎn)是最多的,判斷,選擇,等等一系列的函數(shù),當(dāng)時(shí)熟練使用的時(shí)候,就發(fā)現(xiàn)這東西確實(shí)很有意思。
IF
我們先說最簡單的???if else?
???這也是我們最經(jīng)常使用的判斷,在寫???Shell?
??腳本的時(shí)候,就不像我們的 Java 中直接寫
if(...){
}else{
....
}
??Xshell?
???中的語法就不是這個(gè)樣子的,??Xshell?
?語法:
if ...
then
...
else
...
fi
末尾的 fi 就是 if 倒過來拼寫,我們可以寫一個(gè)???if?
??的腳本試一下這個(gè)流程能否理解。
#! /bin/bash
if [ $1 -gt 2 ];
then
echo "值大于2"
else
echo "值小于2"
exit
fi
這里申明一下,
- ?
?-ge?
?標(biāo)識(shí)的是大于等于符號(hào); - ?
?-le?
?表示的是小于等于符號(hào); - ?
?-gt?
??表示大于符號(hào); - ?
?-lt?
??表示小于符號(hào); - ?
?-eq?
??表示等于符號(hào); - ?
?-ne?
??表示不等于符號(hào);
我們在上面這段腳本中寫就是內(nèi)容就是,我們給腳本傳入一個(gè)值,然后比對(duì)這個(gè)值和2的大小關(guān)系,然后輸出我們指定的內(nèi)容。
運(yùn)行后就能看到
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh test2.sh 1
值小于2
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh test2.sh 3
值大于2
??$1?
???表示我們給 Shell 腳本輸入的第一個(gè)參數(shù),???$0?
?就是你寫的shell腳本本身的名字,$2 是我們給 Shell 腳本傳的第二個(gè)參數(shù)
大家在部署某些項(xiàng)目的時(shí)候,是不是啟動(dòng)命令就很簡潔,就是???sh service.sh start?
???類似這種的,那我們來看看一般這種是怎么寫的,這就用到了另外一塊的內(nèi)容,和???if?
???類似,在 Java 中也有,那就是???Case?
?.
Case
我們先來看看???Case?
??的語法,
??case ... esac?
???實(shí)際上就和 Java 中的 Case 是非常相似的,case 語句匹配一個(gè)值與一個(gè)模式,如果匹配成功,執(zhí)行相匹配的命令.??esac?
?是一個(gè)結(jié)束的標(biāo)志。
case 值 in
匹配值1)
command1
command2
;;
匹配值2)
command1
command2
;;
esac
光說不練,假把式,我們來搞一下試試寫一個(gè)腳本來搞一下。就用我們剛才說的???sh servic.sh start?
??來進(jìn)行測試。
case $1 in
start)
#輸出啟動(dòng)命令
echo "start已經(jīng)開始"
;;
stop)
#輸出停止命令
echo "stop命令執(zhí)行"
;;
esac
exit
我們來看看運(yùn)行結(jié)果
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh service.sh start
start已經(jīng)開始
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh service.sh stop
stop命令執(zhí)行
那么這段 Shell 腳本是什么意思呢?其實(shí)很簡單,匹配我們傳入的第一個(gè)字符,和???start?
???還有???stop?
??進(jìn)行比較,如果匹配上之后,輸出命令,最后退出即可。
是不是感覺沒有那么復(fù)雜了呢?
For
說到流程控制,那么肯定不能不說 for , 畢竟 for 循環(huán)在 Java 中那可是重頭戲。
我們先看他的格式
for i in item1 item2 ... itemN
do
command1
command2
...
commandN
done
那么我們有沒有說像是 Java 中那種 for 循環(huán)一樣的方式呢?比如說這個(gè)??for ((i=1; i<=j; i++))?
?
實(shí)際上也是支持這種的,我們來寫一個(gè)試試。
j=$1
for ((i=1;i<=j;i++))
do
echo $i
done
執(zhí)行一下看看
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh fortest.sh 6
1
2
3
4
5
6
既然有 for 那是不是就有 while 呢?是的,沒錯(cuò),確實(shí)是有 while ,也是循環(huán)的意思,但是寫法有略微不一樣的地方
While
while condition
do
command
done
我們來舉個(gè)嘗試打印九九乘法表來看一下
a=1
b=1
while ((a <=9))
do
while ((b<=a))
do
let "c=a*b" #聲明變量c
echo -n "$a*$b=$c "
let b++
done
let a++
let b=1 #因?yàn)槊總€(gè)乘法表都是1開始乘,所以b要重置
echo "" #顯示到屏幕換行
done
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh whileTest.sh
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
是不是也挺簡單的?
其實(shí) Shell 腳本的編寫一般都是在實(shí)際應(yīng)用中提升,單純的寫測試腳本,也是可以讓自己對(duì)知識(shí)的掌握比較充分,而我們一般都是寫一些比較簡單的腳本,復(fù)雜的不是還有運(yùn)維么?
< END >
告訴大家一個(gè)好消息,Java極客技術(shù)讀者交流群(摸魚為主),時(shí)隔 2 年后再次開放了,感興趣的朋友,可以在公號(hào)回復(fù):999
本文摘自 :https://blog.51cto.com/u