Shell程式設計 | 基本語法 :變數、I/O、算術運算、條件判斷、流程控制、函數

2020-10-28 11:00:55


變數

環境變數

環境變數用於初始化shell的啟動環境,是系統定義的變數。

常用的環境變數有下面幾種
在這裡插入圖片描述
可以使用env命令來檢視所有的環境變數,也可以直接echo檢視某個環境變數的值

位置變數

我們可以使用shift命令來將引數左移,語法如下

shift 表示移動的位數 

每次左移一位

#!/bin/bash

echo $@
shift 1
echo $@
shift 1
echo $@
shift 1
echo $@

在這裡插入圖片描述

特殊變數

$n :表示輸入的第n個引數,當超過十的時候需要用大括號括起來,如${10}
$# :獲取輸入引數的個數
$? :獲取上一條命令的執行狀態,如果為0則說明執行成功,為1則說明執行失敗。當然也可以用於獲取函數返回值
$$ :獲取當前程序的pid
$@ :代表當前命令列中所有的引數,不過它會把每個引數區分對待
$* :代表當前命令列中所有的引數,不過它會把所有引數當成一個整體

自定義變數

定義變數的方式很簡單,只需要給它賦值進行,並且不需要指明型別

變數名=

當需要刪除變數的時候,可以使用unset命令

unset 變數名

如果想要宣告常數,可以使用readonly關鍵字,但是需要注意,常數不可被unset

readonly 變數名

我們還可以通過export命令將區域性變數升級為環境變數

export 變數名

注意事項

  • 等號兩邊不能有空格
  • 如果變數名中存在空格時需要以單引號或者雙引號括起來,否則會被當成命令
  • bash中變數會被預設視為字串型別,無法直接進行算數運算

陣列

定義陣列

陣列名=( 元素1 元素2 元素3 ...... )
# 元素前後以空格為間隔

顯示陣列的所有元素

echo ${陣列名[@]}

顯示陣列的元素個數

echo ${#陣列名[@]}

顯示陣列的第i個元素

echo ${陣列名[i]}

例如
將引數作為陣列元素,檢視陣列中的內容

#!/bin/bash

arr=( $@ )

echo ${arr[@]}
echo ${#arr[@]}
echo ${arr[5]}

在這裡插入圖片描述


I/O

printf / echo

shell中的輸出命令有printf和echo兩種,printf是從C語言中模仿而來,所以它可以指定型別、對其方式等屬性。

echo 輸出
printf 輸出

同時echo輸出時會自帶換行,而printf則需要自己手動加入\n

read

read用於從終端獲取輸入
語法如下

read (選項)(引數)
-p:指定讀取值時的提示符;
-t:指定讀取值時等待的時間(秒)。

範例:從終端獲取一個值並輸出

#!/bin/bash

read -p "請輸入引數:" str
echo $str

在這裡插入圖片描述


算術運算

shell中存在兩種算術運算的命令,分別是let和expr

let

let的語法如下

let 變數名=let 變數名=變數名+值

需要注意的是,當有變數加入運算的時候不需要在變數前面加$
通常為了簡便,我們也會使用兩個圓括號let

((算術式))	# 不需要空格

我們通常以以下兩種方式來獲取計算結果

$((運算式)) 或 $[運算式]

expr

expr用來計算表示式,每一個運運算元之間要有空格,並且當有變數加入時需要加上$

expr  + , - , \*,  /,  %   

條件判斷

test

在shell中我們通常利用test來進行條件判斷,當結果為真時返回0,失敗時返回1

語法如下:

test 判斷內容

不過我們通常都會以方括號的形式進行簡寫,如下

[ 判斷條件 ] # 需要注意的是條件前後需要有空格

常用判斷條件

  1. 判空

-n :非空(nonzero)
-z :為空(zero)

  1. 字串之間比較

= :字串相同           != :字串不同

  1. 整數之間比較

-eq :等於(equal)               -ne :不等於(Not equal)
-lt :小於(less than)            -le :小於等於(less equal)
-gt :大於(greater than)      -ge :大於等於(greater equal)

  1. 判斷檔案許可權

-r :有讀的許可權(read)
-w :有寫的許可權(write)
-x :有執行的許可權(execute)

  1. 判斷檔案型別

-f :檔案存在並且是一個常規的檔案(file)
-e :檔案存在(existence)
-d :檔案存在並是一個目錄(directory)


流程控制

if

if用於進行邏輯判斷,語法格式如下

if test 條件 # 或者使用[ 條件 ]
	then 
	# 執行的命令
elif test 條件	# 進行其他的分支判斷
	then 
	# 執行的命令
else	# 剩餘的情況
	# 執行的命令
fi

例如判斷輸入的數位是否大於十

#!/bin/bash

a=$1

if [ $a -lt 10 ]
    then 
    echo "less than 10"
elif [ $a -gt 10 ]
    then 
    echo "greater than 10"
else
    echo "equal than 10"
fi

在這裡插入圖片描述


case

case用於進行分支選擇,語法格式如下

case $變數名 in
    "值A")
    # 執行分支A
    ;;
    "值B")
    # 執行分支B
    ;;
    "值C")
    # 執行執行分支C
    ;;
    *)
    # 如果不為以上值,則執行預設分支
    ;;
esac

注意事項

  • case行必須以in結尾,每個值必須要用雙引號包含,並以右括號結束
  • ;;代表分支的結束,類似於C中的break
  • *)代表預設模式,類似於C中的default

例如以下使用情況

#!/bin/bash

a=$1
case $a in
    "1")
    echo "11111111111"
    ;;
    "2")
    echo "22222222222"
    ;;
    "3")
    echo "33333333333"
    ;;
    *)
    echo "default"
    ;;
esac

在這裡插入圖片描述


shell中的迴圈控制主要有for,while,until三種

for

shell中的for迴圈有兩種語法,一種是我們傳統的C語言for,另一種則類似C++中的範圍for

# 語法1
for ((初始值; 迴圈條件; 變數變化))
    do
        # 執行命令
    done

# 語法2
for 變數 in 陣列或者區間
    do
        # 執行命令
    done

分別進行演示

計算1到100的累加和

#!/bin/bash

i=0
sum=0
for ((i=0; i<=100; i++))
    do
        sum=$[$sum+$i]
    done

echo $sum

在這裡插入圖片描述
計算輸入的引數之和

#!/bin/bash

sum=0
for i in $@
    do
        sum=$[$sum+$i]
    done

echo $sum

在這裡插入圖片描述


while

while的邏輯是當判斷條件為真時執行迴圈

語法如下

#!/bin/bash

while [ 判斷條件為真則執行 ]
    do
    # 執行命令
    done

until

until與while剛好相反,如果判斷條件為假,則until繼續執行

語法如下

#!/bin/bash

until [ 判斷條件為假則執行 ]
    do
    # 執行命令
    done

函數

系統函數

系統自建的函數庫在路徑 /etc/init.d/functions
常用的主要有basenamedirname兩種,用於解析檔案的路徑

basename通常用於獲取檔名,它會找到最後一個/的位置,並刪除前面所有字元

basename 檔案路徑 [可選: 刪除的字元]

例如
在這裡插入圖片描述

dirname主要用於獲取路徑名,它會去掉檔名,然後返回剩餘的部分

dirname 檔案路徑

在這裡插入圖片描述

自定義函數

shell中也允許自定義函數,語法如下

function 函數名() #括號中不能填任何東西
{
	# 執行命令
	# 返回值
}

注意事項

  • 括號中不能填任何引數,傳參可以直接通過 $變數名的形式傳遞,返回值可以使用特殊變數 $? 獲取。如果沒有宣告返回值,則以函數最後一條命令的結果作為返回值
  • shell指令碼是逐行執行的,所以必須先宣告函數才能呼叫

獲取兩個數相加的結果

function add()
{
    echo $[$1+$2]
}

read -p "請輸入引數A: " a
read -p "請輸入引數B: " b

add $a $b

在這裡插入圖片描述