Shell腳本命令的工作方式有兩種: 互動式(Interactive):用戶每輸入一條命令就立即執行。 批處理(Batch):由用戶事先編寫好一個完整的Shell腳本,Shell會一次性執行腳本中諸多的命令。 一、編寫簡單的腳本 一個Shell腳本主要由三部分組成:腳本聲明、腳本註釋、腳本命令。 腳 ...
Shell腳本命令的工作方式有兩種:
互動式(Interactive):用戶每輸入一條命令就立即執行。
批處理(Batch):由用戶事先編寫好一個完整的Shell腳本,Shell會一次性執行腳本中諸多的命令。
一、編寫簡單的腳本
一個Shell腳本主要由三部分組成:腳本聲明、腳本註釋、腳本命令。
腳本聲明:告訴系統使用哪種Shell解釋器來執行該腳本,比如:#!/bin/bash
腳本註釋:以#開頭,主要是介紹腳本的功能和某些命令
腳本命令:需要被執行的Linux命令。
Shell腳本的名稱可以任意,但為了方便用戶辨認,建議加上.sh尾碼以表示這是一個腳本文件。下麵通過Vim編輯器簡單編寫一個Shell腳本:
[root@linuxprobe ~]# vim example.sh
#!/bin/bash //腳本聲明
# for example by xuliang //腳本註釋
pwd //腳本命令
ls -al
可以通過bash命令直接運行腳本文件,也可以通過輸入完整路徑的方式來執行,但是需要先對腳本文件添加可執行許可權。
[root@linuxprobe ~]# bash example.sh //通過bash命令執行腳本文件
/root
total 21260
dr-xr-x---. 17 root root 4096 Feb 23 16:57 .
drwxr-xr-x. 17 root root 4096 Feb 23 10:34 ..
drwxr-xr-x. 3 root root 14 Feb 18 15:26 a
-rw-------. 1 root root 1032 Feb 18 2019 anaconda-ks.cfg
-rw-------. 1 root root 6039 Feb 23 10:57 .bash_history
---------------------省略部分輸出內容------------------------------
[root@linuxprobe ~]# ./example.sh //通過完整路徑執行腳本文件,需要可執行許可權
-bash: ./example.sh: Permission denied
[root@linuxprobe ~]# chmod u+x example.sh //添加可執行許可權
[root@linuxprobe ~]#
[root@linuxprobe ~]# ./example.sh //腳本執行成功
/root
total 21260
dr-xr-x---. 17 root root 4096 Feb 23 16:57 .
drwxr-xr-x. 17 root root 4096 Feb 23 10:34 ..
drwxr-xr-x. 3 root root 14 Feb 18 15:26 a
-rw-------. 1 root root 1032 Feb 18 2019 anaconda-ks.cfg
-rw-------. 1 root root 6039 Feb 23 10:57 .bash_history
-------------------省略部分輸出內容-----------------------------
二、接收用戶的參數
上面的腳本只能執行一些預先定義好的命令,未免太過於死板了。為了增加Shell腳本的靈活性,必須讓腳本可以接收用戶輸入的參數。Linux系統中的Shell腳本語言已經內設了用於接受參數的變數,變數之間使用空格間隔,相關變數如下所示:
- $0:表示當前Shell腳本的名稱;
- $#:表示總共有幾個參數;
- $*:表示所有位置的參數值
- $1、$2、$3、$4.....:表示第N個位置的參數值。
“百聞不如一見,看書不如實踐”,接下來通過編寫一個腳本,引用上面的變數參數來看一下實際效果:
[root@linuxprobe ~]# vim example.sh
#!/bin/bash
# for example by xuliang
echo "當前腳本名稱$0"
echo "總共有$#個參數,分別是$*"
echo "第一個參數為$1,第3為$3"
[root@linuxprobe ~]# bash example.sh 1 2 3 4 5 6 //傳入6個參數
當前腳本名稱example.sh
總共有6個參數,分別是1 2 3 4 5 6
第一個參數為1,第3為3
三、判斷用戶的參數
接下來學習如何處理接收到的用戶參數。Shell腳本中的條件測試語法可以判斷表達式是否成立,若條件成立則返回數字0,否則返回其他隨機數字(一般都是返回1),條件測試語句的執行格式如下所示。切記,條件表達式兩邊必須要有一個空格。
按照測試對象來劃分,條件測試語句可以分為4種:
-
- 文件測試語句;
- 邏輯測試語句;
- 整數值比較語句;
- 字元串比較語句。
1、文件測試語句
指使用指定條件來判斷文件是否存在或許可權是否滿足等情況的運算符,具體參數如下所示:
運算符 | 作用 |
-d | 測試文件是否為目錄類型 |
-e | 測試文件是否存在 |
-f | 判斷是否為一般文件 |
-r | 測試當前用戶是否有許可權讀取 |
-w | 測試當前用戶是否有許可權寫入 |
-x | 測試當前用戶是否有許可權執行 |
實驗1:使用文件測試語句判斷/etc/fstab是否為一個目錄類型文件,然後通過Shell解釋器的內設$?變數來顯示上一條命令執行後的返回值。如果上一條命令執行成功,則$?變數的數值為0;反之則為一個非零值(一般都是1)。
[root@linuxprobe ~]# [ -d /etc/fstab ]
[root@linuxprobe ~]# echo $? //顯示上條命令執行結果
1 //非零值表示執行失敗
[root@linuxprobe ~]#
實驗2:使用條件測試語句判斷/etc/fstab是否為一個一般文件。
[root@linuxprobe ~]# [ -f /etc/fstab ]
[root@linuxprobe ~]# echo $?
0 //執行成功
[root@linuxprobe ~]#
2、邏輯測試語句
指對測試結果進行邏輯分析,根據測試結果實現不同的效果。主要有3種邏輯運算符,如下所示:
運算符 | 作用 |
邏輯與(&&) | 表示前面的命令執行成功後,才執行後面的命令 |
邏輯或(||) | 表示前面的命令執行失敗後,才執行後面的命令 |
邏輯非(!) | 表示把條件測試語句中的判斷結果取相反值 |
實驗1:判斷/dev/cdrom文件是否存在,若存在則輸出Exist字樣。
[root@linuxprobe ~]# [ -e /dev/cdrom ] && echo "Exist" //邏輯與
Exist
實驗2:判斷當前登錄的用戶是否為管理員身份:
[root@linuxprobe ~]# su - linuxprobe //切換至linuxprobe用戶
Last login: Mon Feb 24 10:26:51 BNT 2020 on pts/1
[linuxprobe@linuxprobe ~]$
[linuxprobe@linuxprobe ~]$ [ $USER = root ] || echo "not root" //邏輯或
not root
實驗3:判斷當前登錄用戶為非管理員身份:
[linuxprobe@linuxprobe ~]$ su - root //切換至root用戶
Password:
Last login: Mon Feb 24 11:13:05 BNT 2020 on pts/1
[root@linuxprobe ~]# [ ! $USER = root ] || echo "It's root" //邏輯非
It's root
實驗4:判斷當前登錄的用戶,若是普通用戶則輸出“user”,若是管理員用戶則輸出“root”
[root@linuxprobe ~]# [ ! $USER = root ] && echo "user" || echo "It's root"
It's root //root用戶
[root@linuxprobe ~]# su - linuxprobe //切換至linuxprobe用戶
Last login: Mon Feb 24 14:41:29 BNT 2020 on pts/1
[linuxprobe@linuxprobe ~]$ [ ! $USER = root ] && echo "user" || echo "It's root"
user //普通用戶
3、整數比較運算符
僅僅是對數字的操作,即運算符的兩邊必須是數字,不能將數字與字元串、文件等內容一起操作,而且一定要使用規範的整數比較運算符來進行操作。整數比較運算符如下所示:
運算符 | 作用 |
-eq | 是否等於 |
-ne | 是否不等於 |
-gt | 是否大於(greater than) |
-lt | 是否小於(less than) |
-le | 是否等於或小於 |
-ge | 是否大於或等於 |
實驗:判斷當前主機空閑記憶體是否小於1024M,若小於1024M,則輸出“Insufficient Memory”的字樣。
[linuxprobe@linuxprobe ~]$ FreeMem=`free -m | grep Mem: | awk '{print $4}'` //獲取當前主機空閑記憶體值,註意賦值號的兩邊不能有空格
[linuxprobe@linuxprobe ~]$
[linuxprobe@linuxprobe ~]$ [ $FreeMem -lt 1024 ] && echo "Insuficient Memory"
Insuficient Memory
4、字元串比較語句
用於判斷測試字元串是否為空值,或兩個字元串是否相同,常見的字元串運算符如下所示:
運算符 | 作用 |
= | 比較字元串的內容是否相同 |
!= | 比較字元串的內容是否不同 |
-z | 判斷字元串的內容是否為空 |
實驗1:判斷變數String是否空值,即判斷是否定義了該變數。
[linuxprobe@linuxprobe ~]$ [ -z $String ]
[linuxprobe@linuxprobe ~]$ echo $?
0
實驗2:判斷當前LANG環境變數值是否為“en.US”。
[linuxprobe@linuxprobe ~]$ echo $LANG
en_US.UTF-8
[linuxprobe@linuxprobe ~]$ [ $LANG = "en.US" ] || echo "Not en.US"
Not en.US
四、流程式控制制語句
在Shell腳本中,我們可以通過if、for、while、case這4中流程式控制制語句來編寫難度更大、功能更強的腳本,來匹配實際的生產需求。
1、if條件測試語句