《Linux從入門到精通》之shell編程

shell變量

變量名和等號(hào)之間不能有有空格,變量名命名遵循以下規(guī)則。

  • 命名只能使用英文字母,數(shù)字和下劃線,首個(gè)字符不能以數(shù)字開頭。
  • 中間不能有空格,可以使用下劃線(_)。
  • 不能使用bash里的關(guān)鍵字(可用help命令查看保留關(guān)鍵字)。
my_name="Tomandy"
echo ${my_name}            #輸出 Tomandy
echo ${my_name}123         #輸出 Tomandy123

使用關(guān)鍵字readonly可以將變量定義為只讀變量,該類型變量的值不能被改變。

myname="Tomandy"
readonly myname
myname="andy"              #執(zhí)行報(bào)錯(cuò) myname只讀變量

unset可以刪除變量,但是不能刪除只讀變量。

myname="Tomandy"
unset myname
echo ${myname}             #執(zhí)行沒有任何輸出

shell字符串

單引號(hào)字符串和雙引號(hào)字符串的區(qū)別。

  • 單引號(hào)里的任何字符都會(huì)原樣輸出,單引號(hào)字符串中的變量是無(wú)效的。
  • 單引號(hào)字串中不能出現(xiàn)單引號(hào)(對(duì)單引號(hào)使用轉(zhuǎn)義符后也不行)。
  • 雙引號(hào)里可以有變量。
  • 雙引號(hào)里可以出現(xiàn)轉(zhuǎn)義字符。
myname='myname is tomandy'
echo '${myname}'            #輸出 ${myname}
echo "${myname}"            #輸出 myname is tomandy

獲取字符串長(zhǎng)度

string="Lin 123"
echo ${#string}             #輸出 7
expr length "$string"       #輸出 7,注意由于string變量有空格,變量需加上“”

提取子字符串

string="myname is Tomandy"
echo ${string:1:4}          # 輸出 ynam,表示從第二個(gè)字符開始,截取4個(gè)字符

字符串截取的其他方法如下:
假設(shè)有變量 var=http://www.aaa.com/123.htm

  1. # 號(hào)截取,刪除左邊字符,保留右邊字符。
echo ${var#*//} 
# 其中 var 是變量名,# 號(hào)是運(yùn)算符,*// 表示從左邊開始刪除第一個(gè) //號(hào)及左邊的所有字符,即刪除http://
# 輸出結(jié)果是 :www.aaa.com/123.htm
  1. ## 號(hào)截取,刪除左邊字符,保留右邊字符。
echo ${var##*/}
# “##*/” 表示從左邊開始刪除最后(最右邊)一個(gè)/號(hào)及左邊的所有字符,即刪除 http://www.aaa.com/
# 輸出結(jié)果是 :123.htm
  1. %號(hào)截取,刪除右邊字符,保留左邊字符。
echo ${var%/*}
# %/* 表示從右邊開始,刪除第一個(gè) / 號(hào)及右邊的字符,即/123.htm
# 輸出結(jié)果是:http://www.aaa.com
  1. %% 號(hào)截取,刪除右邊字符,保留左邊字符。
echo ${var%%/*}
# %%/* 表示從右邊開始,刪除最后(最左邊)一個(gè) / 號(hào)及右邊的字符
# 輸出結(jié)果是:http:
  1. 從左邊第幾個(gè)字符開始,一直到結(jié)束。
echo ${var:7}
# 其中的 7 表示左邊第8個(gè)字符開始,一直到結(jié)束。
# 輸出結(jié)果是 :www.aaa.com/123.htm
  1. 從右邊第幾個(gè)字符開始,及字符的個(gè)數(shù)。
echo ${var:0-7:3}
# 其中的 0-7 表示右邊算起第七個(gè)字符開始,3 表示字符的個(gè)數(shù)。
# 輸出結(jié)果是:123
  1. 從右邊第幾個(gè)字符開始,一直到結(jié)束
echo ${var:0-7}
# 表示從右邊第七個(gè)字符開始,一直到結(jié)束。
# 輸出結(jié)果是:123.htm

查找字符串

string="Tomandy is a man"
echo `expr index "$string" is`  #輸出9,注意此處使用了反引號(hào),而不是單引號(hào)

shell數(shù)組

在Shell中,用括號(hào)來(lái)表示數(shù)組,數(shù)組元素用"空格"符號(hào)分割開。定義及讀取數(shù)組如下所示:

array_name=(value0 value1 value2 value3) #定義數(shù)組
value=${array_name[n]}    #讀取數(shù)組某個(gè)元素值
echo ${array_name[@]}     #獲取數(shù)組所有元素
length=${#array_name[@]}  #獲取數(shù)組個(gè)數(shù)
length=${#array_name[*]}  #獲取數(shù)組個(gè)數(shù)
lengthn=${#array_name[n]} #取得數(shù)組單個(gè)元素的長(zhǎng)度

數(shù)組的值也可以寫入變量,如:my_array=($A B C D),A為變量。

shell參數(shù)傳遞

我們可以在執(zhí)行 Shell 腳本時(shí),向腳本傳遞參數(shù),腳本內(nèi)獲取參數(shù)的格式為:$n。n 代表一個(gè)數(shù)字,1 為執(zhí)行腳本的第一個(gè)參數(shù),2 為執(zhí)行腳本的第二個(gè)參數(shù),以此類推……

參數(shù)處理 說(shuō)明
$# 傳遞到腳本的參數(shù)個(gè)數(shù)
$* 以一個(gè)單字符串顯示所有向腳本傳遞的參數(shù)。如"$*"用「"」括起來(lái)的情況、以"$1 $2 … $n"的形式輸出所有參數(shù)。
$$ 腳本運(yùn)行的當(dāng)前進(jìn)程ID號(hào)
$! 后臺(tái)運(yùn)行的最后一個(gè)進(jìn)程的ID號(hào)
$@ 與$*相同,但是使用時(shí)加引號(hào),并在引號(hào)中返回每個(gè)參數(shù)。 顯示最后命令的退出狀態(tài)。0表示沒有錯(cuò)誤,其他任何值表明有錯(cuò)誤。如"$@"用「"」括起來(lái)的情況、以"$1" "$2" … "$n" 的形式輸出所有參數(shù)。
$? 顯示最后命令的退出狀態(tài)。0表示沒有錯(cuò)誤,其他任何值表明有錯(cuò)誤。

其他特殊字符:

參數(shù)處理 說(shuō)明
$# 傳遞到腳本的參數(shù)個(gè)數(shù)
$* 以一個(gè)單字符串顯示所有向腳本傳遞的參數(shù)。如"$*"用「"」括起來(lái)的情況、以"$1 $2 … $n"的形式輸出所有參數(shù)。
$$ 腳本運(yùn)行的當(dāng)前進(jìn)程ID號(hào)
$! 后臺(tái)運(yùn)行的最后一個(gè)進(jìn)程的ID號(hào)
$@ 與$*相同,但是使用時(shí)加引號(hào),并在引號(hào)中返回每個(gè)參數(shù)。 顯示最后命令的退出狀態(tài)。0表示沒有錯(cuò)誤,其他任何值表明有錯(cuò)誤。如"$@"用「"」括起來(lái)的情況、以"$1" "$2" … "$n" 的形式輸出所有參數(shù)。
$? 顯示最后命令的退出狀態(tài)。0表示沒有錯(cuò)誤,其他任何值表明有錯(cuò)誤。

$* 與 $@ 區(qū)別:
相同點(diǎn):都是引用所有參數(shù)。
不同點(diǎn):只有在雙引號(hào)中體現(xiàn)出來(lái)。假設(shè)在腳本運(yùn)行時(shí)寫了三個(gè)參數(shù) 1、2、3,,則 " * " 等價(jià)于 "1 2 3"(傳遞了一個(gè)參數(shù)),而 "@" 等價(jià)于 "1" "2" "3"(傳遞了三個(gè)參數(shù))。通過(guò)循環(huán)打印可以發(fā)現(xiàn)差異。

shell文件測(cè)試運(yùn)算符

文件測(cè)試運(yùn)算符.png

echo命令

標(biāo)準(zhǔn)輸入:read 命令一個(gè)一個(gè)詞組地接收輸入的參數(shù),每個(gè)詞組需要使用空格進(jìn)行分隔;如果輸入的詞組個(gè)數(shù)大于需要的參數(shù)個(gè)數(shù),則多出的詞組將被作為整體為最后一個(gè)參數(shù)接收。

#!/bin/sh
read name    #read 命令從標(biāo)準(zhǔn)輸入中讀取一行,并把輸入行的每個(gè)字段的值指定給 shell 變量
echo "$name It is a test"

顯示換行:

echo -e "OK! \n"    # -e 開啟轉(zhuǎn)義
echo "It it a test"
#輸出結(jié)果
OK!  

It it a test

顯示不換行:

#!/bin/sh
echo -e "OK! \c"      # -e 開啟轉(zhuǎn)義 \c 不換行
echo "It is a test"
#輸出結(jié)果
OK! It it a test

其他示例:

read -p "請(qǐng)輸入一段文字:" -n 6 -t 5 -s password
echo -e "\npassword is $password"  #-e開啟轉(zhuǎn)義
  • -p 輸入提示文字
  • -n 輸入字符長(zhǎng)度限制(達(dá)到6位,自動(dòng)結(jié)束)
  • -t 輸入限時(shí)
  • -s 隱藏輸入內(nèi)容
#執(zhí)行結(jié)果
$ sh test.sh 
請(qǐng)輸入一段文字:
password is asdfgh

test命令

test命令等價(jià)于[],下圖兩段代碼輸出結(jié)果為“兩個(gè)數(shù)相等”

num1=100
num2=100
if test ${num1} -eq ${num2}
then
    echo '兩個(gè)數(shù)相等!'
else
    echo '兩個(gè)數(shù)不相等!'
fi
num1=100
num2=100
if [ ${num1} -eq ${num2} ]
then
    echo '兩個(gè)數(shù)相等!'
else
    echo '兩個(gè)數(shù)不相等!'
fi

Shell 流程控制

if else語(yǔ)法

if condition
then
    command1 
    command2
    ...
    commandN 
fi
if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi
if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

for循環(huán):

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
#!/bin/bash
for((i=1;i<=5;i++));do
    echo "這是第 $i 次調(diào)用";
done;

while循環(huán):

#!/bin/sh
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"       #用于執(zhí)行一個(gè)或多個(gè)表達(dá)式,變量計(jì)算中不需要加上 $ 來(lái)表示變量
done
#while循環(huán)可用于讀取鍵盤信息。下面的例子中,輸入信息被設(shè)置為變量FILM,按<Ctrl-D>結(jié)束循環(huán)。
echo '按下 <CTRL-D> 退出'
echo -n '輸入你最喜歡的網(wǎng)站名: '
while read FILM
do
    echo "是的!$FILM 是一個(gè)好網(wǎng)站"
done

case:case的語(yǔ)法和C family語(yǔ)言差別很大,它需要一個(gè)esac(就是case反過(guò)來(lái))作為結(jié)束標(biāo)記,每個(gè)case分支用右圓括號(hào),用兩個(gè)分號(hào)表示break。

echo '輸入 1 到 4 之間的數(shù)字:'
echo '你輸入的數(shù)字為:'
read aNum
case $aNum in
    1)  echo '你選擇了 1'
    ;;
    2)  echo '你選擇了 2'
    ;;
    3)  echo '你選擇了 3'
    ;;
    4)  echo '你選擇了 4'
    ;;
    *)  echo '你沒有輸入 1 到 4 之間的數(shù)字'
    ;;
esac

shell函數(shù)

舉例如下:

#!/bin/bash

demoFun(){
    echo "這是我的第一個(gè) shell 函數(shù)!"
}
echo "-----函數(shù)開始執(zhí)行-----"
demoFun
echo "-----函數(shù)執(zhí)行完畢-----"


#輸出結(jié)果
-----函數(shù)開始執(zhí)行-----
這是我的第一個(gè) shell 函數(shù)!
-----函數(shù)執(zhí)行完畢-----
#!/bin/bash

funWithReturn(){
    echo "這個(gè)函數(shù)會(huì)對(duì)輸入的兩個(gè)數(shù)字進(jìn)行相加運(yùn)算..."
    echo "輸入第一個(gè)數(shù)字: "
    read aNum
    echo "輸入第二個(gè)數(shù)字: "
    read anotherNum
    echo "兩個(gè)數(shù)字分別為 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "輸入的兩個(gè)數(shù)字之和為 $? !"      #函數(shù)返回值在調(diào)用該函數(shù)后通過(guò) $? 來(lái)獲得。 


#輸出結(jié)果
這個(gè)函數(shù)會(huì)對(duì)輸入的兩個(gè)數(shù)字進(jìn)行相加運(yùn)算...
輸入第一個(gè)數(shù)字: 
1
輸入第二個(gè)數(shù)字: 
2
兩個(gè)數(shù)字分別為 1 和 2 !
輸入的兩個(gè)數(shù)字之和為 3 !
#在Shell中,調(diào)用函數(shù)時(shí)可以向其傳遞參數(shù)。在函數(shù)體內(nèi)部,通過(guò) $n 的形式來(lái)獲取參數(shù)的值,例如,$1表示第一個(gè)參數(shù),$2表示第二個(gè)參數(shù)...
#!/bin/bash

funWithParam(){
    echo "第一個(gè)參數(shù)為 $1 !"
    echo "第二個(gè)參數(shù)為 $2 !"
    echo "第十個(gè)參數(shù)為 $10 !"
    echo "第十個(gè)參數(shù)為 ${10} !"
    echo "第十一個(gè)參數(shù)為 ${11} !"
    echo "參數(shù)總數(shù)有 $# 個(gè)!"
    echo "作為一個(gè)字符串輸出所有參數(shù) $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

/dev/null 文件

如果希望執(zhí)行某個(gè)命令,但又不希望在屏幕上顯示輸出結(jié)果,那么可以將輸出重定向到 /dev/null。
/dev/null 是一個(gè)特殊的文件,寫入到它的內(nèi)容都會(huì)被丟棄;如果嘗試從該文件讀取內(nèi)容,那么什么也讀不到。但是 /dev/null 文件非常有用,將命令的輸出重定向到它,會(huì)起到"禁止輸出"的效果。

Shell 文件包含

創(chuàng)建兩個(gè) shell 腳本文件。
test1.sh 代碼如下:

#!/bin/bash

url="http://www.runoob.com"

test2.sh 代碼如下:

#!/bin/bash

#使用 . 號(hào)來(lái)引用test1.sh 文件
. ./test1.sh

# 或者使用以下包含文件代碼
# source ./test1.sh

echo "網(wǎng)址:$url"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,707評(píng)論 0 5
  • .bat腳本基本命令語(yǔ)法 目錄 批處理的常見命令(未列舉的命令還比較多,請(qǐng)查閱幫助信息) 1、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,531評(píng)論 1 19
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 13,209評(píng)論 2 33
  • 第 3 章目錄: 3.1 shell 語(yǔ)法3.2 shell 命令3.3 shell 函數(shù)3.4 shell 參數(shù)...
    C86guli閱讀 6,603評(píng)論 2 4
  • 基礎(chǔ) 頭文件 #!/bin/bash 或者#!/bin/sh #!約定的標(biāo)記,如IOS的Import 執(zhí)行文件時(shí)需...
    ZMJun閱讀 1,320評(píng)論 1 2

友情鏈接更多精彩內(nèi)容