• 正文
    • 一、變量
    • 二、shell 功能語句
    • 三、shell 分支語句
    • 四、shell 循環(huán)語句
    • 五、shell 函數(shù)
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

Linux基礎(chǔ)-shell腳本編程

02/02 11:45
289
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

一、變量

1. shell腳本基礎(chǔ)知識

編譯型語言:如 c語言
解釋型語言:shell 腳本

shell腳本的本質(zhì):shell命令的有序集合。

2.shell 編程的基本過程

基本過程分為三步:

    建立shell文件:包含任意多行操作系統(tǒng)命令或shell命令的文本文件。——xx.sh賦予shell文件執(zhí)行權(quán)限,==用chmod命令修改權(quán)限==。執(zhí)行shell文件,直接在命令行上調(diào)用shell程序

示例:

    建立shell文件 ?prog1.sh
data
    賦予shell文件執(zhí)行權(quán)限 (初始文本文件無執(zhí)行權(quán)限)
chmod?740?prog1.sh
#或者
chmod?u+x?prog1.sh
    執(zhí)行shell文件
prog1.sh
#結(jié)果為
prog1.sh :not?found

原因是:shell在標(biāo)準(zhǔn)搜索路徑中找不到prog1.sh
4.正確的執(zhí)行shell文件

./prog1.sh
#結(jié)果為
2009年?12月?16日?星期二?14:52:57?CST

3. shell變量

shell允許用戶建立變量存儲數(shù)據(jù),但不支持?jǐn)?shù)據(jù)類型(整型,字符,浮點型),將任何賦給變量的值都解釋為一串字符Variable = value

    • count = 1echo $ countDATE =

data

    echo $ ?DATE

在這里插入圖片描述

==注意幾點:==

變量沒有類型

=號兩邊不能加空格

變量必須是大寫

賦值的時候要用``框起來

Bourne shell有如下四種變量:

用戶自定義變量:

      1. 在shell編程中通常使用全大寫變量:COUNT=1變量的調(diào)用,在變量前加$:echo $HOMELinux shell / bash 從右向左賦值:Y=y、X=$Y、echo $X 、y使用unset命令刪除變量的賦值:Z=hello、echo $Z、hello、unset Z、echo$Z

位置變量及命令行參數(shù):

    1. $0 與鍵入的命令行一樣,包含腳本文件名$1,$2....$9 分別包含第一個到第九個命令行參數(shù)?!? 包含命令行參數(shù)的個數(shù)$@ 包含所有命令行參數(shù):$1,$2,...$9$?包含前一個命令的退出狀態(tài)$* ? ?包含所有命令行參數(shù):$1,$2,....$9$$ 包含正在執(zhí)行進(jìn)程的ID號

    預(yù)定義變量

必須在兩位數(shù)邊寫上 { } ,才能正常值一一樣。

    環(huán)境變量

    1. HOME:/etc/passwd文件中列出的用戶目錄IFS: Internal Field Separator , 默認(rèn)為空格,tab及換行符PATH:shell搜索路徑PS1,PS2:默認(rèn)提示符($)及換行提示符(>)TERM:終端類型,常用的有vt100,ansi,vt200,xterm等。

二、shell 功能語句

shell 程序由零或多條shell語句構(gòu)成。shell語句包括三類:說明性語句,功能性語句和結(jié)構(gòu)性語句。

**說明性語句 ** 以 # 號開始到該行結(jié)束,不被解釋執(zhí)行功能性語句 任意的shell命令,用戶程序或其他shell程序結(jié)構(gòu)性語句 條件測試語句,多路分支語句,循環(huán)語句,循環(huán)控制語句等。

#!/bin/sh
#
#?本程序說明
#
command_1
command_2?????#command_2的語句說明
....

常用功能性語句(命令)

==read== 從標(biāo)準(zhǔn)輸入讀入一行,并賦值給后面的變量,其語法為:

read?var

把讀入的數(shù)據(jù)全部賦給var

read?var1?var2?var3

把讀入行中的第一個單詞(word)賦給var1 ,第二個單詞賦給var2,.....把其余所有的詞賦給最后一個變量。如果執(zhí)行read語句時標(biāo)準(zhǔn)輸入無數(shù)據(jù),則程序在此停留等候,直到數(shù)據(jù)的到來或被終止運行。

#!/bin/bash
echo?"input?a?number:"
read?NUM
echo?$NUM

在這里插入圖片描述

#!/bin/bash
echo?"input?year?month?day:"
read?Y?M?D
echo?"Today?is?$Y-$M-$D"

==expr命令:==算術(shù)運算命令expr主要用于進(jìn)行簡單的整數(shù)運算,包括加(+)、減(-)、乘(*)和求模(%)等操作。例如

$expr?12?+?5?*?3
27
$expr?3?-?8?/?2
-1
$num=9
$sum=`expr?$num?*?6`
$echo?$sum
54

?。∵\算符間用空格分開??!

測試語句

==test語句==

test語句可測試三種對象:

字符串 ?/ 整數(shù) ?/ 文件屬性

每種測試對象都有若干測試操作符
例如:

test?"$answer"?=?"yes"
#變量answer的值是否為字符串yes

test?$num?-eq?18
#變量num的值是否為整數(shù)18

test?-d?tmp
#測試tmp?是否為一個目錄名

字符串測試:

s1 = s2 測試兩個字符串的內(nèi)容是否完全一樣
s1 ?!= ?s2 測試兩個字符串的內(nèi)容是否有差異
-z s1 測試s1 ?字符串的長度是否為0
-n s1 測試s1 ?字符串的長度是否不為0

整數(shù)測試:

a - eq b 測試a 與 b是否相等
a - ne b 測試a 與 b是否不相等
a - gt b 測試a 是否大于b
a - ge b 測試a 是否大于相等b
a - lt b 測試a 是否小于b
a - le b 測試a 是否小于等于b
#!/bin/bash

A="how"
B="hoW"
test?$A?=?$B
echo?$????//表示輸出前一個語句的結(jié)果

在這里插入圖片描述

#!/bin/bash

A="how"
B="how"
test?$A?=?$B
echo?$????//表示輸出前一個語句的結(jié)果

相等為0(真),不等為1(假)

#!/bin/bash

A="how"
B="hoW"
test?$A?=?$B
echo?$????//表示輸出前一個語句的結(jié)果

pwd
echo?$?

ls?file
echo?$?

最后ls file 沒有,所以結(jié)果為2

#!/bin/bash

A=99
B=88
test?$A?-ne??$B
echo?$????//表示輸出前一個語句的結(jié)果

test?$A?-gt??$B
echo?$????//表示輸出前一個語句的結(jié)果

三、shell 分支語句

1. 條件語句

==if ..then...fi==語法結(jié)構(gòu):

if???表達(dá)式
??????????????then??命令表
fi???
    如果表達(dá)式為真,則執(zhí)行命令表種的命令;否則退出if語句,即執(zhí)行fi后面的語句if和fi是條件語句的語句括號,必須成對使用;命令表中的命令可以是一條,也可以是若干條。
#!/bin/bash

if?[?$#?-ne?1?]
then???
???????echo?"usage?:?$0?filename"
???????exit
fi
if?!?[?-e??$1?]
then?
????????echo?"?$1?not?exist"
????????exit
fi?
if?[?-d?$1?]
then
?????????echo?"$1?is?a?dirextory"
fi

if...then ..else..fi
語句結(jié)構(gòu)為:

if????表達(dá)式
then???命令表1
else????命令表2
fi

如果表達(dá)式為真,則執(zhí)行命令表1中的命令,在退出if語句;否則執(zhí)行命令表2中的語句,在退出if語句。

注意:無論表達(dá)式是否為真,都有語句要執(zhí)行

#!/bin/bash

if?[?$#?-ne?1?]
then???
???????echo?"usage?:?$0?filename"
???????exit
fi
if?!?[?-e??$1?]
then?
????????echo?"?$1?not?exist"
????????exit
fi?
if?[?-L?$1?]
then
?????????echo?"l"
elif?[?-d?$1?]
then
?????????echo?"-"
elif?[?-b?$1?]
then?
?????????echo?"b"
else
?????????echo?"csp"
fi

在這里插入圖片描述

2. 多路分支語句

==case...esac==多路分支語句case用于多重條件測試,語法結(jié)構(gòu)清晰自然,

case??字符串變量???in???//case語句只能檢測字符串變量
??????模式1)
???????????????命令表1??//各模擬中可用文件名元字符,以右括號結(jié)束
???????????????;;
??????模式2?|?模式3)
???????????????命令表2
???????????????;;????//命令表以單獨的雙分號行結(jié)束,退出case語句
.....
模式n)
????????????????命令表n
????????????????;;?????//模式n常寫為字符*,表示所有其他模式
esac????????????????????//最后一個雙分號行可以省略

判斷選擇——多路分支語句 示例1:

#!/bin/bash

echo?-n?"please choose (yes | no)?"
read?R
case?$R?in
????????yes?|?Yes?|y?|?Y?|YES?)
?????????????echo??"yes"
?????????????;;?
?????????no)
?????????????echo??"no"
?????????????;;
?????????*)
?????????????echo???"wrong"
?????????????#;;
esac

判斷成績——多路分支語句 示例2:

#!/bin/bash

echo?-n?"please choose (yes | no)?"
read?S
if?[?$S?-lt?0?-o?$S?-gt?100]
then?
????????echo?"no?in?[0-100]"
????????exit??????
fi

G=`expr?$S?/?10`
case?$G?in
????????9|10)
?????????????echo??"$S?A"
?????????????;;?
?????????6|7|8)
?????????????echo??"$S?B"
?????????????;;
?????????*)
?????????????echo???"$S?C"
?????????????#;;
esac

在這里插入圖片描述

四、shell 循環(huán)語句

1. 循環(huán)語句for的用法

當(dāng)循環(huán)次數(shù)已經(jīng)知道或確定時候,使用for循環(huán)語句來多次執(zhí)行一條或者一組命令,循環(huán)體由語句括號do和done來限定。

格式為:

for????變量名????in???單詞表
?????????do??
?????????????????????命令表
??????????done

變量依次取單詞表中的各個單詞,每取一次單詞,就執(zhí)行一次循環(huán)體中的命令。循環(huán)次數(shù)由單詞數(shù)確定。命令表中的命令可以是一條,也可以是由分號或換行符分開的多條。如果單詞表是命令行上的所有位置參數(shù)時,可以在for

實例代碼:

#!/bin/bash

#for?I??in?`ls?/etc`
do??
???????echo?"$I"
done

在這里插入圖片描述

==seq命令== ?:列出一系列的數(shù)字seq ? 起始數(shù)字 ? 中間分量 ? 終止分量

#!/bin/bash
for?I?in?`seq?1?2?10`
do
??????echo?"$I"
done

示例:拷貝當(dāng)前目錄下的所有文件到backup子目錄下。使用語法為:./prog5.sh[filename]

#The?statement?of?for?....do...done
if?[!?-d?$HOME/backup?]
then
????????mkdir?$HOME/backup
fi
flist=`ls`
for?file?in?$flist???//flist的值是ls的執(zhí)行結(jié)果即當(dāng)前目錄下的文件名
do
?????if?[?$#?=?1?]
?????then
?????????????if?[?$1?=?$file?]???//命令行上有一個參數(shù)時
?????????????then
????????????????????????echo?"$file?found"?;??exit
?????????????fi
??????else?
?????????????cp?$file?$HOME/backup
?????????????echo?"$file?copied"???
??????fi
done
echo??***Backup?Completed******???????????

2. 循環(huán)語句while的用法

語法結(jié)構(gòu):

while????命令或表達(dá)式
??????????do
???????????????命令表
??????????done

while語句首先測試其后的命令或表達(dá)式的值,如果為真,就執(zhí)行一次循環(huán)體中的命令,然后再測試該命令或表達(dá)式的值,執(zhí)行循環(huán)體,直到該命令或表達(dá)式為假時退出循環(huán)。

示例:

#!/bin/bash

I=0

while?[?$I?-lt?5?]???//-lt??=??<
do
??????I=`expr?$I?+?1`
??????echo?-n?"input?score:"
??????read?$S

??????case?`expr?$S?/?10`?in
?????????9|10)
??????????????echo?"A"
??????????????;;
????????6|7|8)
??????????????echo?"B"
??????????????;;
????????*)
??????????????echo?"C"
??????????????;;
????esac
????echo?"$I"
done

3. 循環(huán)控制語句

==break 和 continue==

break ?n 則跳出n層;continue語句則馬上轉(zhuǎn)到最近的一層循環(huán)語句的下一輪循環(huán)上,
continue n 則轉(zhuǎn)到最近n層循環(huán)語句的下一輪循環(huán)上。

用法:prog7 整數(shù) 整數(shù) 整數(shù) ...
參數(shù)個數(shù)不確定,范圍為1-10個 ,每個參數(shù)都是正整數(shù)。

示例:

#!/bin/bash

if?[?$#?-ne?5?]
then?
??????echo?"argument?5"
??????exit
fi

for?I
do
????if?[?`expr?$I?%?2`?-eq?1?]
????then
?????????echo?"$I"
?????????else
????????????????break
????fi
done????????

若是break 的話 ,跳出整個循環(huán)。遇到偶數(shù)就跳出循環(huán)。

#!/bin/bash

if?[?$#?-ne?5?]
then?
??????echo?"argument?5"
??????exit
fi

for?I
do
????if?[?`expr?$I?%?2`?-eq?1?]
????then
?????????echo?"$I"
?????????else
????????????????continue
????fi
done????????

若是continue的話 ,跳出當(dāng)前循環(huán)。遇到偶數(shù)就跳出當(dāng)前循環(huán),繼續(xù)執(zhí)行下面語句

五、shell 函數(shù)

1. shell函數(shù)調(diào)用

函數(shù)調(diào)用格式:

方式1:
value_name=`function_name??[arg1?arg2?...]`

函數(shù)的所有標(biāo)準(zhǔn)輸出都傳遞給了主程序的變量

方式2:
function_name?[arg1?arg2?...]
echo?$?

獲取函數(shù)的返回狀態(tài)

獲取函數(shù)的返回狀態(tài) ——示例:

grep_user()
{
???R=`grep?"$1"?/etc/passwd?|?wc?-l`
???echo?$R
???return?$R
}

echo?-n?"input?username:"
read?USER
grep_user?$USER
RET=$?
if?[?$USER?-eq?1?]
then???
???????echo?"$USER?exist"
else
???????echo?"$USER?not?exist"
fi

若改為不返回值,用變量,函數(shù)的所有標(biāo)準(zhǔn)輸出都傳遞給了主程序的變量

grep_user()
{
???R=`grep?"$1"?/etc/passwd?|?wc?-l`
???echo?$R
}

echo?-n?"input?username:"
read?USER
RET=`grep_user?$USER`
echo?"----return?$RET-----"
if?[?$USER?-eq?1?]
then???
???????echo?"$USER?exist"
else
???????echo?"$USER?not?exist"
fi

在這里插入圖片描述

2. 函數(shù)變量作用域

    • 全局作用域:在腳本的其他任何地方都能夠訪問該變量局部作用域:只能在聲明變量的作用域內(nèi)訪問聲明局部變量的格式:

c Local variable_name = value

grep_user()
{
??????B=200
??????A=100
}

grep_user
echo?"end:?$A-$B"

結(jié)果發(fā)現(xiàn)函數(shù)內(nèi)的變量,竟然是全局變量

如果我們要局部變量就 加一個local

grep_user()
{
??????B=200
??????local?A=100
}

grep_user
echo?"end:?$A-$B"

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

公眾號『一口Linux』號主彭老師,擁有15年嵌入式開發(fā)經(jīng)驗和培訓(xùn)經(jīng)驗。曾任職ZTE,某研究所,華清遠(yuǎn)見教學(xué)總監(jiān)。擁有多篇網(wǎng)絡(luò)協(xié)議相關(guān)專利和軟件著作。精通計算機網(wǎng)絡(luò)、Linux系統(tǒng)編程、ARM、Linux驅(qū)動、龍芯、物聯(lián)網(wǎng)。原創(chuàng)內(nèi)容基本從實際項目出發(fā),保持原理+實踐風(fēng)格,適合Linux驅(qū)動新手入門和技術(shù)進(jìn)階。