天天看點

Shell程式設計基本知識

shell程式設計的基本寫法及文法,摘自菜鳥教程
http://www.runoob.com/linux/linux-shell.html
           

寫一個shell腳本:

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

“#!”是标記使用哪種shell解釋器來執行shell,echo是輸出後面的文本。

講檔案儲存成xxxx.sh,然後需要給這個xxxx.sh加上執行權限,使用指令

chmod +x ./xxxx.sh,由于xxxx.sh是shell腳本,沒有在系統的PATH中,是以直接找xxxx.sh是不存在的,是以要加上./,并且執行時也要加上./xxxx.sh。

定義一個變量:

sss=”sss” # 注意:這裡等号的左右不能出現空格,否則将報錯

使用變量則必須加上 符号,否則無法識别,如果在字元串中通路變量,則需要将變量名稱使用括起來,如 {sss}

如果要定義隻讀變量,則隻需要定義完變量之後另起一行在變量前加上readonly即可,如 readonly sss

删除變量 unset sss,注意,unset不能删除隻讀變量

shell字元串

單引号:寫在單引号裡面的字元串,不論什麼,都會原樣輸出,包括轉義符号;

雙引号:可以有變量,可以出現轉義符。

字元串的拼接不需要“+”,這與其他程式設計語言有差別。

如sss = “xxx” sss即可。擷取字元串長度為 {#sss}。

截取字元串: sss:1:2,與python的清單/字元串切片操作有點像。bash隻支援一維數組,并且沒有大小限定,下标從0開始。資料定義arraysss=1234,可以看出,shell的數組元素之間不需要分隔符。讀取數組元素同樣使用下标完成,讀取所有的元素則可以使用 {array_sss[@]}。

shell裡面的注釋隻能使用“#”進行單行注釋,沒有多行注釋。

shell的參數傳遞

shell的參數傳遞是根據數字編号來擷取的,編号為0的,指的就是shell腳本本身,後邊的參數對應的編号依次類推。

如執行: ./xxxx.sh a b 則對應編号0的參數為./xxxx.sh 1->a 2->b。

$# 傳遞到腳本的參數個數
$* 以一個單字元串顯示所有向腳本傳遞的參數。
               如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數。
$$    腳本運作的目前程序ID号
$! 背景運作的最後一個程序的ID号
$@ 與$*相同,但是使用時加引号,并在引号中傳回每個參數。
               如"$@"用「"」括起來的情況、以"$1" "$2" … "$n" 的形式輸出所有參數。
$- 顯示Shell使用的目前選項,與set指令功能相同。
$? 顯示最後指令的退出狀态。表示沒有錯誤,其他任何值表明有錯誤。
           

shell的基本運算符

算數運算符、關系運算符、布爾運算符、字元串運算符、檔案測試運算符等

原生的bash不支援簡單的數學運算,但可以通過其他指令來實作,例如awk和expr。

#!/bin/bash
val=`expr  + `
echo "兩數之和為 : $val"
           

注意兩點:val後的引号為

反引号

,2 + 2 的加号兩邊必須留白格

假定變量 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。==相等。用于比較兩個數字,相同則傳回true。[ a == b]傳回false。!=不相等。用于比較兩個數字,不相同則傳回true。[ a != $b ] 傳回 true。

關系運算符隻支援數字,不支援字元串,除非字元串的值是數字。

下表列出了常用的關系運算符,假定變量 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。

假定變量 a 為 10,變量 b 為 20:

運算符 說明 舉例

!   非運算,表達式為 true 則傳回 false,否則傳回 true。  [ ! false ] 傳回 true。
-o  或運算,有一個表達式為 true 則傳回 true。                               [ $a -lt  -o $b -gt  ] 傳回 true。
-a  與運算,兩個表達式都為 true 才傳回 true。              [ $a -lt  -a $b -gt  ] 傳回 false。

假定變量 a 為 ,變量 b 為 :
運算符 說明  舉例
&&  邏輯的 AND [[ $a -lt 100 && $b -gt 100 ]] 傳回 false
||  邏輯的 OR  [[ $a -lt 100 || $b -gt 100 ]] 傳回 true
           

假定變量 a 為 “abc”,變量 b 為 “efg”:

運算符              說明                                                                                 舉例
=   檢測兩個字元串是否相等,相等傳回 true。                [ $a = $b ] 傳回 false。
!=  檢測兩個字元串是否相等,不相等傳回 true。 [ $a != $b ] 傳回 true。
-z  檢測字元串長度是否為,為傳回 true。                [ -z $a ] 傳回 false。
-n  檢測字元串長度是否為,不為傳回 true。             [ -n $a ] 傳回 true。
str 檢測字元串是否為空,不為空傳回 true。                 [ $a ] 傳回 true。
           
操作符             說明                                      舉例                                                                                                             

-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 檢測檔案是否為空(檔案大小是否大于),不為空傳回 true。[ -s $file ] 傳回 true。
-e file 檢測檔案(包括目錄)是否存在,如果是,則傳回 true。    [ -e $file ] 傳回 true。
           

Shell的流程控制

if else-if else塊
基本文法
if condition
then
    command
elif
then
    command
else
    command
fi
           

for 循環

基本文法

for var in item1 item2 …itemN 
do
    command
done
           

寫成一行

for var in item1 item2 ... itemN; do command; command2… done;
           

while語句

while condition
do
    command
done
           

無限循環 ‘while ;’ 或 ‘while true’ 或 for(( ; ; ))

until 循環

執行一系列指令,直到特定條件時停止。

until condition
do
          command
done
           

case

基本文法

case 值 in
    模式)
        command
        ;;      
    模式)
               command
        ;;
    *) 
        other command
        ;;
esac
           

跳出循環

break 終止執行後面的所有循環

#!/bin/bash
while :
do
    echo -n "輸入 1 到 5 之間的數字:"
    read aNum
    case $aNum in
        ||||) echo "你輸入的數字為 $aNum!"
        ;;
        *) echo "你輸入的數字不是 1 到 5 之間的! 結束"
            break
        ;;
    esac
done
           

continue 跳出目前循環,不結束循環。

Shell函數

shell函數定義格式:

[ function ] funname [()]
{
    action;
    [return int;]
}
           

1、可以帶function fun() 定義,也可以直接fun() 定義,不帶任何參數。

2、參數傳回,可以顯示加:return 傳回,如果不加,将以最後一條指令運作結果,作為傳回值。 return後跟數值n(0-255)

3、傳回值通過$?來獲得。

4、函數必須定義在使用前,否則無法找到函數。

函數參數擷取:

函數名 參數1 參數2 … 參數N

注意:當參數大于10個的時候,使用 10不能擷取參數,需要使用 {10}來擷取。

$# 傳遞到腳本的參數個數
$* 以一個單字元串顯示所有向腳本傳遞的參數
$$    腳本運作的目前程序ID号
$! 背景運作的最後一個程序的ID号
$@ 與$*相同,但是使用時加引号,并在引号中傳回每個參數。
$- 顯示Shell使用的目前選項,與set指令功能相同。
$? 顯示最後指令的退出狀态。表示沒有錯誤,其他任何值表明有錯誤。
           

重定向指令清單如下:

指令 說明

command > file 将輸出重定向到 file。

command < file 将輸入重定向到 file。

command >> file 将輸出以追加的方式重定向到 file。

n > file 将檔案描述符為 n 的檔案重定向到 file。

n >> file 将檔案描述符為 n 的檔案以追加的方式重定向到 file。

n >& m 将輸出檔案 m 和 n 合并。

n <& m 将輸入檔案 m 和 n 合并。

<< tag 将開始标記 tag 和結束标記 tag 之間的内容作為輸入。

重定向深入講解

一般情況下,每個 Unix/Linux 指令運作時都會打開三個檔案:

标準輸入檔案(stdin):stdin的檔案描述符為0,Unix程式預設從stdin讀取資料。

标準輸出檔案(stdout):stdout 的檔案描述符為1,Unix程式預設向stdout輸出資料。

标準錯誤檔案(stderr):stderr的檔案描述符為2,Unix程式會向stderr流中寫入錯誤資訊。

預設情況下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

如果希望 stderr 重定向到 file,可以這樣寫:

command2>file如果希望stderr追加到file檔案末尾,可以這樣寫: command 2 >> file

2 表示标準錯誤檔案(stderr)。

如果希望将 stdout 和 stderr 合并後重定向到 file,可以這樣寫:

command > file 2>&1  

或者 command >> file 2>&1

如果希望對 stdin 和 stdout 都重定向,可以這樣寫:

$ command < file1 >file2

command 指令将 stdin 重定向到 file1,将 stdout 重定向到 file2。

Shell 檔案包含

和其他語言一樣,Shell 也可以包含外部腳本。這樣可以很友善的封裝一些公用的代碼作為一個獨立的檔案。

Shell 檔案包含的文法格式如下:

. filename # 注意點号(.)和檔案名中間有一空格

source filename