當前位置:首頁 > IT技術 > 系統(tǒng)服務 > 正文

一文教你如何學會寫Shell腳本
2022-02-14 14:19:13

一文教你如何學會寫Shell腳本_java

做 Java 的肯定都接觸過 Linux 系統(tǒng),那么很多時候我們在開發(fā)的過程中都是把我們項目打成一個jar包,或者是war包的形式,然后通過 XFTP 上傳到我們服務器的指定目錄,然后運行一端啟動腳本,讓我們項目變得可以訪問 就像???./sh service.sh start???然后啟動我們寫好的???sh???的shell腳本。接下來我們就來學習一下關于 Shell 腳本是如何寫出來的。

Shell 腳本

Shell 腳本是什么?Shell是一個命令解釋器,它的作用是解釋執(zhí)行用戶輸入的命令及程序等,也就是說,我們用戶每輸入一條命令,Shell 就會相對應的執(zhí)行一條命令。當命令或程序語句不在命令行下執(zhí)行,而是通過一個程序文件來執(zhí)行時,該程序文件就被稱為Shell腳本。

在我們的 Shell 腳本中,會有各種各樣的內容,賦值,計算,循環(huán)等一系列的操作,接下來我們就來看看這個 Shell 腳本怎么寫吧

1.查看自己當前系統(tǒng)默認的 Shell

??echo $SHELL??

輸出:/bin/bash

2.查看系統(tǒng)支持的Shell

??cat /etc/shells??

輸出:

/bin/sh /bin/bash /usr/bin/sh /usr/bin/bash

也就是說,我們的云服務器是支持我們在這里給他安排 Shell 腳本的

Shell 腳本怎么寫出來的

我們這時候先來安排一下???sh????的文件,創(chuàng)建一個文件夾,然后在其中創(chuàng)建一個???sh???的文件。

??mkdir /usr/local/shelltest??

??touch test.sh??

創(chuàng)建完成我們編輯一下內容

??vim test.sh??

#!/bin/bash
echo "Hello World Shell"

然后我們出來運行一下我們的 Shell 的第一個腳本

??bash test.sh??

出來的結果是???Hello World Shell??

一個及其簡單的腳本出現(xiàn)了,接下我們就分析一波我們寫了點啥?

??#!/bin/bash??

#! 是一個約定的標記,它告訴系統(tǒng)這個腳本需要什么解釋器來執(zhí)行,即使用哪一種 Shell

我們在之前也使用了???echo $SHELL????來查看了自己系統(tǒng)默認的是哪一種???sh???解析器,之前看到的是/bin/bash,所以我們在寫 Shell 腳本的時候,我們在開頭默認的約定中,我們寫了這個是用 /bin/bash 來進行解釋的,

那么我們如何像之前調用我們的當前目錄中的 Shell 腳本一樣去調用他呢?就像這個樣子的???./sh service.sh start??

1.授權,

我們先不授權試一下看看能通過 ./test.sh 進行調用么

bash: ./test.sh: Permission denied 會提示這個,也就是沒有授權定義,

授權命令:chmod +x test.sh

2.執(zhí)行 ./test.sh

然后調用就能正常輸出了,就是說,在當前的目錄下執(zhí)行這個腳本命令。

Shell 腳本的變量
  1. 定義變量和使用

變量命名實際上很簡單,我們先來試一下

??name=zhiyikeji??

這時候我們怎么使用變量呢?實際上只要在前面加上一個符號就可以 $

??echo $name??

[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name
zhiyikeji
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo ${name}
zhiyikeji

上面的兩種寫法都是可以的,外面的大括號加和不加區(qū)別不大,可以省略,直接就??$name???就可以使用你定義的變量

使用括號的意義一般在于區(qū)別某些變量,比如你寫了一串的內容,可能寫的是???echo $nameismyfriend???,如果連在一起,是不是有點尷尬,這時候就可以使用括號區(qū)別一下,??echo ${name}ismyfriend???不使用括號的時候,他就去找nameismyfriend這個變量了,就無法出來我們要的效果。

  1. 刪除自己定義的變量

??unset name??

這時候我們就把我們剛才定義的???name=zhiyikeji???這個變量給去掉了,我們可以調用一下我們的變量看是什么?

??echo $name??

[root@iZbp10j01t7sgfqekyefpoZ ~]# unset name
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name

這是不是就證明我們自己定義的變量已經刪除了

  1. 只讀變量

那么我們需要一個關鍵字,大家肯定能想到是什么關鍵字???readonly??

我們先給name賦值,然后使用 readonly 設置只讀,然后再改變一下試試,

[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 ~]#

竟然是真的,如果不設置只讀,是不是會重新可以進行賦值,我們測試個年齡,

[root@iZbp10j01t7sgfqekyefpoZ ~]# age=10
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $age
10
[root@iZbp10j01t7sgfqekyefpoZ ~]# age=20
[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $age
20

所以我們就可以肯定,readonly就是設置只讀的關鍵詞,記住了么?

那么設置只讀的變量可以刪除么?畢竟總有杠精的面試官會提問這個棘手的問題,但是,阿粉試過的所有方式好像都是不行的,阿粉就直接重啟了自己的服務器,這樣臨時的變量就不存在了!

Shell 腳本的流程控制

說真的,Shell腳本的流程控制數(shù)一般才是yyds,為什么這么說,因為你在寫大部分的腳本的時候,流程控制的地方永遠是最多的,判斷,選擇,等等一系列的函數(shù),當時熟練使用的時候,就發(fā)現(xiàn)這東西確實很有意思。

IF

我們先說最簡單的???if else????這也是我們最經常使用的判斷,在寫???Shell???腳本的時候,就不像我們的 Java 中直接寫

if(...){

}else{
....
}

??Xshell????中的語法就不是這個樣子的,??Xshell??語法:

if ...
then

...
else
...
fi

末尾的 fi 就是 if 倒過來拼寫,我們可以寫一個???if???的腳本試一下這個流程能否理解。

#! /bin/bash

if [ $1 -gt 2 ];


then
echo "值大于2"

else
echo "值小于2"

exit
fi

這里申明一下,


  • ??-ge??標識的是大于等于符號;
  • ??-le??表示的是小于等于符號;
  • ??-gt???表示大于符號;
  • ??-lt???表示小于符號;
  • ??-eq???表示等于符號;
  • ??-ne???表示不等于符號;

我們在上面這段腳本中寫就是內容就是,我們給腳本傳入一個值,然后比對這個值和2的大小關系,然后輸出我們指定的內容。

運行后就能看到

[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh test2.sh 1
值小于2
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh test2.sh 3
值大于2

??$1????表示我們給 Shell 腳本輸入的第一個參數(shù),???$0??就是你寫的shell腳本本身的名字,$2 是我們給 Shell 腳本傳的第二個參數(shù)

大家在部署某些項目的時候,是不是啟動命令就很簡潔,就是???sh service.sh start????類似這種的,那我們來看看一般這種是怎么寫的,這就用到了另外一塊的內容,和???if????類似,在 Java 中也有,那就是???Case??.

Case

我們先來看看???Case???的語法,

??case ... esac????實際上就和 Java 中的 Case 是非常相似的,case 語句匹配一個值與一個模式,如果匹配成功,執(zhí)行相匹配的命令.??esac??是一個結束的標志。

case 值 in
匹配值1)
command1
command2

;;
匹配值2)
command1
command2
;;
esac

光說不練,假把式,我們來搞一下試試寫一個腳本來搞一下。就用我們剛才說的???sh servic.sh start???來進行測試。

case $1 in

start)
#輸出啟動命令
echo "start已經開始"
;;
stop)
#輸出停止命令
echo "stop命令執(zhí)行"
;;
esac
exit

我們來看看運行結果

[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh service.sh start
start已經開始
[root@iZbp10j01t7sgfqekyefpoZ shelltest]# sh service.sh stop
stop命令執(zhí)行

那么這段 Shell 腳本是什么意思呢?其實很簡單,匹配我們傳入的第一個字符,和???start????還有???stop???進行比較,如果匹配上之后,輸出命令,最后退出即可。

是不是感覺沒有那么復雜了呢?

For

說到流程控制,那么肯定不能不說 for , 畢竟 for 循環(huán)在 Java 中那可是重頭戲。

我們先看他的格式

for i in item1 item2 ... itemN
do
command1
command2
...
commandN
done

那么我們有沒有說像是 Java 中那種 for 循環(huán)一樣的方式呢?比如說這個??for ((i=1; i<=j; i++))??

實際上也是支持這種的,我們來寫一個試試。

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 呢?是的,沒錯,確實是有 while ,也是循環(huán)的意思,但是寫法有略微不一樣的地方

While
while condition
do
command
done

我們來舉個嘗試打印九九乘法表來看一下

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 #因為每個乘法表都是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

是不是也挺簡單的?

其實 Shell 腳本的編寫一般都是在實際應用中提升,單純的寫測試腳本,也是可以讓自己對知識的掌握比較充分,而我們一般都是寫一些比較簡單的腳本,復雜的不是還有運維么?


< END >

告訴大家一個好消息,Java極客技術讀者交流群(摸魚為主),時隔 2 年后再次開放了,感興趣的朋友,可以在公號回復:999

一文教你如何學會寫Shell腳本_shell腳本_02


本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務立即開通 >