1. 程式人生 > 其它 >菜鳥教程shell學習筆記整理(一):基礎知識

菜鳥教程shell學習筆記整理(一):基礎知識

shell學習筆記
一、基礎知識

1、版本型別:Bash

2、經典入門案例:Hello World !

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

3、執行shell指令碼的兩種方法
shell指令碼一般已".sh"作為字尾,以檔案"test.sh"為例
(1)作為可執行程式來執行的shell程式,執行命令為
chmod +x ./test.sh #使指令碼具有執行許可權
./test.sh #執行指令碼
寫成./test.sh是為了宣告該檔案在當前目錄下,否則會在系統變數的PATH路徑中查詢
(2)作為解釋其引數來執行,可以直接寫成sh [/path/]test.sh
在當前目錄下直接執行
在其他目錄下需要補全絕對路徑

4、shell變數
(1)shell變數命名只能使用英文字母,數字和下劃線,首個字元不能以數字開頭,也不能使用內建函式
使用一個定義過的變數,只要在變數名前面加"$"即可,最好在引用變數的時候加上花括號,用於直譯器識別變數的邊界,如下所示

# 定義變數your_name
your_name="qinjx"
# 輸出變數$your_name
echo $your_name
# 輸出帶有花括號的變數$your_name,防止在拼接時因為無法確定邊界造成的錯誤
echo ${your_name}

(2)使用readonly可以將變數宣告為無法修改的只讀變數,如下所示

#!/bin/bash
your_name="
qinjx" readonly your_name your_name="aabb" echo ${your_name} 輸出結果為: qinjx script.sh: line 4: your_name: readonly variable

(3)使用unset命令可以刪除變數,如下所示

your_name="qinjx"
unset your_name
echo ${your_name}

沒有輸出結果

(4)shell變數型別
a、區域性變數:區域性變數在指令碼或命令中定義,僅在當前shell例項中有效,其他shell啟動的程式不能訪問區域性變數。
b、環境變數:所有的程式,包括shell啟動的程式,都能訪問環境變數,有些程式需要環境變數來保證其正常執行。必要的時候shell指令碼也可以定義環境變數。
c、hell變數:shell變數是由shell程式設定的特殊變數。shell變數中有一部分是環境變數,有一部分是區域性變數,這些變數保證了shell的正常執行
(5)shell字串
a、單引號字串的限制:
單引號裡的任何字元都會原樣輸出,單引號字串中的變數是無效的;
單引號字串中不能出現單獨一個的單引號(對單引號使用轉義符後也不行),但可成對出現,作為字串拼接使用。
b、雙引號的優點:
雙引號裡可以有變數
雙引號裡可以出現轉義字元
如下所示

#!/bin/bash
your_name="runoob"
# 使用雙引號拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1
# 使用單引號拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2  $greeting_3
輸出結果
hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !
c、獲取字串長度
string="abcd"
echo ${#string} #輸出 4
d、字串擷取
echo ${變數:開始位置(預設起始位置為0):擷取長度}
e、查詢字串
#查詢字元 i 或 o 的位置(哪個字母先出現就計算哪個)
string="runoob is a great site"
echo `expr index "$string" io`  # 輸出 4  `是反引號

5、shell陣列
bash支援一維陣列
a、陣列定義
陣列名=(值1 值2 ... 值n)
或者
陣列名[0]=值1
陣列名[1]=值2
……
陣列名[n]=值n+1
b、讀取陣列
#制定下標讀取
valuen=${array_name[n]}
#全部讀取
valuen=${array_name[@]}
# 取得陣列元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得陣列單個元素的長度
lengthn=${#array_name[n]}
c、shell註釋
單行註釋只要在行前面加"#"
多行註釋可用如下方式
:<<EOF
註釋內容...
EOF

6、傳參
(1)、向指令碼傳遞引數,指令碼內獲取引數的格式為:$n。n 代表一個數字,1 為執行指令碼的第一個引數,2 為執行指令碼的第二個引數,以此類推。
建立test.sh指令碼,在其中輸入如下程式碼

#!/bin/bash
# author:菜鳥教程
# url:www.runoob.com

echo "Shell 傳遞引數例項!";
echo "執行的檔名:$0";
echo "第一個引數為:$1";
echo "第二個引數為:$2";
echo "第三個引數為:$3";
此時,$0、$1、$2、$3就是用來儲存傳入引數的變數名,當執行test.sh指令碼時,依次輸入四個引數即可實現引數的傳遞,執行語句如下
$ chmod +x test.sh 
$ ./test.sh 1 2 3
返回結果為
Shell 傳遞引數例項!
執行的檔名:./test.sh
第一個引數為:1
第二個引數為:2
第三個引數為:3

(2)、常見處理引數的特殊字元
$# : 傳遞到指令碼的引數個數
$* : 以一個單字串顯示所有向指令碼傳遞的引數。如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有引數。
$$ : 指令碼執行的當前程序ID號
$! : 後臺執行的最後一個程序的ID號
$@ : 與$*相同,但是使用時加引號,並在引號中返回每個引數。如"$@"用「"」括起來的情況、以"$1" "$2" … "$n" 的形式輸出所有引數。
$- : 顯示Shell使用的當前選項,與set命令功能相同。
$? : 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。
在test.sh指令碼中輸入如下程式碼

#!/bin/bash
# author:菜鳥教程
# url:www.runoob.com

echo "Shell 傳遞引數例項!";
echo "第一個引數為:$1";

echo "引數個數為:$#";
echo "傳遞的引數作為一個字串顯示:$*";
執行指令碼並傳參後的結果如下
$ chmod +x test.sh 
$ ./test.sh 1 2 3
Shell 傳遞引數例項!
第一個引數為:1
引數個數為:3
傳遞的引數作為一個字串顯示:1 2 3

(3)、$* 與 $@ 區別:
相同點:都是引用所有引數。
不同點:只有在雙引號中體現出來。
假設在指令碼執行時寫了三個引數 1、2、3,,則 " * " 等價於 "1 2 3"(傳遞了一個引數),而 "@" 等價於 "1" "2" "3"(傳遞了三個引數)

7、shell的運算子
shell支援多種運算子,包括算數運算子,關係運算符,布林運算子,字串運算子,檔案測試運算子
(1)、算數運算子
原生bash不支援簡單的數學運算,但是可以通過其他命令來實現,例如 awk 和 expr,expr 最常用
算數運算子在使用時,需要用反引號將表示式擴進去,用來宣告計算使用,引數,括號和運算子之間都需要用空格隔開,否則會被誤認為是字串
假定變數 a 為 10,變數 b 為 20
+ --> 加法 -----------------------------------------> `expr $a + $b` --> 30。
- --> 減法 -----------------------------------------> `expr $a - $b` --> -10。
* --> 乘法 -----------------------------------------> `expr $a \* $b` --> 200。
/ --> 除法 -----------------------------------------> `expr $b / $a` --> 2。
% --> 取餘 -----------------------------------------> `expr $b % $a` --> 0。
= --> 賦值 -----------------------------------------> a=$b --> 將把變數 b 的值賦給 a。
== --> 相等。 -----------------------------------------> [ $a == $b ] --> 用於比較兩個數字,相同則返回 true。返回 false。
!= --> 不相等。 ---------------------------------------> [ $a != $b ] --> 用於比較兩個數字,不相同則返回 true。返回 true。
(2)、關係運算符
關係運算符只支援數字,不支援字串,除非字串的值是數字,假定變數 a 為 10,變數 b 為 20
-eq ---------------> 檢測兩個數是否相等,相等返回 true。 -----------------------------> [ $a -eq $b ] 返回 false。
-ne ---------------> 檢測兩個數是否不相等,不相等返回 true。 -------------------------> [ $a -ne $b ] 返回 true。
-gt ---------------> 檢測左邊的數是否大於右邊的,如果是,則返回 true。 ---------------> [ $a -gt $b ] 返回 false。
-lt ---------------> 檢測左邊的數是否小於右邊的,如果是,則返回 true。 ---------------> [ $a -lt $b ] 返回 true。
-ge ---------------> 檢測左邊的數是否大於等於右邊的,如果是,則返回 true。 -----------> [ $a -ge $b ] 返回 false。
-le ---------------> 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 -----------> [ $a -le $b ] 返回 true。
(3)、布林運算子
假定變數 a 為 10,變數 b 為 20
! ---------> 非運算,表示式為 true 則返回 false,否則返回 true。 -----------> [ ! false ] -------------------> 返回 true。
-o ---------> 或運算,有一個表示式為 true 則返回 true。-----------------------> [ $a -lt 20 -o $b -gt 100 ] ---> 返回 true。
-a ---------> 與運算,兩個表示式都為 true 才返回 true。-----------------------> [ $a -lt 20 -a $b -gt 100 ] ---> 返回 false。
(4)、字串運算子
假定變數 a 為 "abc",變數 b 為 "efg"
= -------> 檢測兩個字串是否相等,相等返回 true。 -----------> [ $a = $b ] 返回 false。
!= -------> 檢測兩個字串是否不相等,不相等返回 true。 ------> [ $a != $b ] 返回 true。
-z -------> 檢測字串長度是否為0,為0返回 true。 -------------> [ -z $a ] 返回 false。
-n -------> 檢測字串長度是否不為 0,不為 0 返回 true。 ------> [ -n "$a" ] 返回 true。
$ -------> 檢測字串是否為空,不為空返回 true。 -------------> [ $a ] 返回 true
(5)、檔案測試運算子
-b file ---------> 檢測檔案是否是塊裝置檔案,如果是,則返回 true。-----------------------------------> [ -b $file ] 返回 false。
-c file ---------> 檢測檔案是否是字元裝置檔案,如果是,則返回 true。 --------------------------------> [ -c $file ] 返回 false。
-d file ---------> 檢測檔案是否是目錄,如果是,則返回 true。 ----------------------------------------> [ -d $file ] 返回 false。
-f file ---------> 檢測檔案是否是普通檔案(既不是目錄,也不是裝置檔案),如果是,則返回 true。 -----> [ -f $file ] 返回 true。
-g file ---------> 檢測檔案是否設定了 SGID 位,如果是,則返回 true。 --------------------------------> [ -g $file ] 返回 false。
-k file ---------> 檢測檔案是否設定了粘著位(Sticky Bit),如果是,則返回 true。 ----------------------> [ -k $file ] 返回 false。
-p file ---------> 檢測檔案是否是有名管道,如果是,則返回 true。 ------------------------------------> [ -p $file ] 返回 false。
-u file ---------> 檢測檔案是否設定了 SUID 位,如果是,則返回 true。 --------------------------------> [ -u $file ] 返回 false。
-r file ---------> 檢測檔案是否可讀,如果是,則返回 true。 ------------------------------------------> [ -r $file ] 返回 true。
-w file ---------> 檢測檔案是否可寫,如果是,則返回 true。 ------------------------------------------> [ -w $file ] 返回 true。
-x file ---------> 檢測檔案是否可執行,如果是,則返回 true。 ----------------------------------------> [ -x $file ] 返回 true。
-s file ---------> 檢測檔案是否為空(檔案大小是否大於0),不為空返回 true。 -------------------------> [ -s $file ] 返回 true。
-e file ---------> 檢測檔案(包括目錄)是否存在,如果是,則返回 true。 ------------------------------> [ -e $file ] 返回 true。
如下例所示

#!/bin/bash
# author:菜鳥教程
# url:www.runoob.com

file="/var/www/runoob/test.sh"
if [ -r $file ]
then
   echo "檔案可讀"
else
   echo "檔案不可讀"
fi
if [ -w $file ]
then
   echo "檔案可寫"
else
   echo "檔案不可寫"
fi
if [ -x $file ]
then
   echo "檔案可執行"
else
   echo "檔案不可執行"
fi
if [ -f $file ]
then
   echo "檔案為普通檔案"
else
   echo "檔案為特殊檔案"
fi
if [ -d $file ]
then
   echo "檔案是個目錄"
else
   echo "檔案不是個目錄"
fi
if [ -s $file ]
then
   echo "檔案不為空"
else
   echo "檔案為空"
fi
if [ -e $file ]
then
   echo "檔案存在"
else
   echo "檔案不存在"
fi
輸出結果如下
檔案可讀
檔案可寫
檔案可執行
檔案為普通檔案
檔案不是個目錄
檔案不為空
檔案存在