1. 程式人生 > 其它 >寫好Shell指令碼,自動化部署就不愁了!

寫好Shell指令碼,自動化部署就不愁了!

點選“終碼一生”,關注,置頂公眾號

每日技術乾貨,第一時間送達!

做 Java 的肯定都接觸過 Linux 系統,那麼很多時候我們在開發的過程中都是把我們專案打成一個jar包,或者是war包的形式,然後通過 XFTP 上傳到我們伺服器的指定目錄,然後執行一端啟動指令碼,讓我們的專案變得可以訪問 就像 ./sh service.sh start 然後啟動我們寫好的 sh 的shell指令碼。接下來我們就來學習一下關於 Shell 指令碼是如何寫出來的。

1、Shell 指令碼

Shell 指令碼是什麼?

Shell是一個命令直譯器,它的作用是解釋執行使用者輸入的命令及程式等,也就是說,我們使用者每輸入一條命令,Shell 就會相對應的執行一條命令。當命令或程式語句不在命令列下執行,而是通過一個程式檔案來執行時,該程式檔案就被稱為Shell指令碼。

在我們的 Shell 指令碼中,會有各種各樣的內容,賦值,計算,迴圈等一系列的操作,接下來我們就來看看這個 Shell 指令碼怎麼寫吧!

1.檢視自己當前系統預設的 Shell

echo$SHELL

輸出:/bin/bash

2.檢視系統支援的Shell

cat/etc/shells

輸出:/bin/sh /bin/bash /usr/bin/sh /usr/bin/bash

也就是說,我們的雲伺服器是支援我們在這裡給他安排 Shell 指令碼的

2、Shell 指令碼怎麼寫出來的

我們這時候先來安排一下 sh 的檔案,建立一個資料夾,然後在其中建立一個 sh 的檔案。

mkdir/usr/local/shelltest
touch test.sh

建立完成我們編輯一下內容

vimtest.sh
#!/bin/bash
echo"Hello World Shell"

然後我們出來執行一下我們的 Shell 的第一個指令碼

bash test.sh

出來的結果是 Hello World Shell

一個及其簡單的指令碼出現了,接下我們就分析一波我們寫了點啥?

#!/bin/bash
#! 是一個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種 Shell

我們在之前也使用了 echo $SHELL 來查看了自己系統預設的是哪一種 sh 解析器,之前看到的是/bin/bash,所以我們在寫 Shell 指令碼的時候,我們在開頭預設的約定中,我們寫了這個是用 /bin/bash 來進行解釋的,

那麼我們如何像之前呼叫我們的當前目錄中的 Shell 指令碼一樣去呼叫他呢?就像這個樣子的 ./sh service.sh start

1.授權

我們先不授權試一下看看能通過 ./test.sh 進行呼叫麼

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

授權命令:chmod +x test.sh

2.執行 ./test.sh

然後呼叫就能正常輸出了,就是說,在當前的目錄下執行這個指令碼命令。

3、Shell 指令碼的變數

定義變數和使用

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

name=zhiyikeji

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

echo $name

[root@iZbp10j01t7sgfqekyefpoZ ~]# echo $name
zhiyikeji

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

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

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

刪除自己定義的變數

unset name

這時候我們就把我們剛才定義的 name=zhiyikeji 這個變數給去掉了,我們可以呼叫一下我們的變數看是什麼?

echo $name

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

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

只讀變數

那麼我們需要一個關鍵字,大家肯定能想到是什麼關鍵字 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:readonlyvariable
[root@iZbp10j01t7sgfqekyefpoZ ~]#

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

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

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

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

4、Shell 指令碼的流程控制

說真的,Shell指令碼的流程控制數一般才是yyds,為什麼這麼說,因為你在寫大部分的指令碼的時候,流程控制的地方永遠是最多的,判斷,選擇,等等一系列的函式,當時熟練使用的時候,就發現這東西確實很有意思。

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]#shtest2.sh1
值小於2
[root@iZbp10j01t7sgfqekyefpoZ shelltest]#shtest2.sh3
值大於2

$1 表示我們給 Shell 指令碼輸入的第一個引數, $0就是你寫的shell指令碼本身的名字,$2 是我們給 Shell 指令碼傳的第二個引數

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

Case

我們先來看看 Case 的語法,

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

case值in
匹配值1)
command1
command2

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

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

case$1in

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

我們來看看執行結果

[root@iZbp10j01t7sgfqekyefpoZ shelltest]#shservice.shstart
start已經開始
[root@iZbp10j01t7sgfqekyefpoZ shelltest]#shservice.shstop
stop命令執行

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

是不是感覺沒有那麼複雜了呢?

For

說到流程控制,那麼肯定不能不說 for , 畢竟 for 迴圈在 Java 中那可是重頭戲。

我們先看他的格式

foriinitem1 item2 ... itemN
do
command1
command2
...
commandN
done

那麼我們有沒有說像是 Java 中那種 for 迴圈一樣的方式呢?比如說這個for ((i=1; i<=j; i++))

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

j=$1
for((i=1;i<=j;i++))
do
echo$i
done

執行一下看看

[root@iZbp10j01t7sgfqekyefpoZ shelltest]#shfortest.sh6
1
2
3
4
5
6

既然有 for 那是不是就有 while 呢?是的,沒錯,確實是有 while ,也是迴圈的意思,但是寫法有略微不一樣的地方

While
whilecondition
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"
letb++
done
leta++

letb=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 指令碼的編寫一般都是在實際應用中提升,單純的寫測試指令碼,也是可以讓自己對知識的掌握比較充分,而我們一般都是寫一些比較簡單的指令碼,複雜的不是還有運維麼?

PS:防止找不到本篇文章,可以收藏點贊,方便翻閱查詢哦。