1. 程式人生 > >shell指令碼總結

shell指令碼總結

shell總結

shell指令碼的本質是shell命令的有序集合

建立shell指令碼的步驟:建立shell指令碼,編寫任意多行作業系統命令或shell命令,增加檔案的執行許可權,結束

shell變數

shell允許使用者建立變數儲存資料,但不支援資料型別。將任何賦給變數的值都解釋為一串字元

shell有如下四種變數:使用者自定義變數,位置變數,預定義變數,環境變數

使用者自定義變數:

定義變數:COUNT=1

使用時前面加$echo $COUNT

刪除變數的賦值:unset COUNT

位置變數:

$0  與鍵入的命令列一樣,包含指令碼檔名

$1,$2...$9  分別包含第一個到第九個命令列引數

$#  包含命令列引數的個數

[email protected]  包含所有命令列引數:“$1,$2...$9 

$?  包含前一個命令的退出狀態

$*  包含所有命令列引數:“$1,$2...$9 

$$  包含正在執行程序的ID

shell環境變數

CDPATH  用於cd命令的查詢路徑

HOME  使用者主目錄

PATH  路徑

shell 程式和語句

shell程式由0nshell語句構成,shell語句包括三大類:功能性語句、結構性語句、說明性語句

說明性語句:以#開始的部分,不被解釋執行

可以出現在程式的任意位置,可以單獨一行,也可以接在執行語句的後面

功能性語句

:任意作業系統命令、shell內部命令、自程式設計序、等

read  從標準輸入讀出一行,賦給後面的變數

read var   #把讀入的資料全部賦給var

read var1 var2 var3     #把讀入一行的第一、二個詞分別賦給var1var2,其他的都賦給var3

如果執行read語句時標準輸入無資料,則程式在此停留等候,直到資料到來或終止執行

expr  主要用於簡單的整數運算,包括 +  -  \*  /   %  

 反撇號用於引用命令的執行結果

test  用於測試三種物件:字串、整數、檔案屬性

可用[  ]代替,注意左右都至少一個空格

如:test  “$answer”  =  

yes”  #變數answer的值是否為字串yes

test  $num  -eq  18  #變數num的值是否為整數18

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

結構性語句:條件測試語句、多路分支語句、迴圈語句、迴圈控制語句、後臺執行語句

條件測試語句

if...then...else...fi

語法結構:

if  表示式

then  

命令表1  #一條或者若干條命令

else

命令表2  #一條或者若干條命令

fi

如果表示式為真,執行命令表1,否則執行命令表2

例子;

if [ -f S1 ]     #測試引數是否為檔案

then

echo “File $1 exists”

fi

if [-d $HOME/$1]   #測試引數是否為目錄

then

echo “File $1 is a directory”

fi

多路分支語句

case...esac

語法結構:

case 字串變數  in     #case語句只能檢測字串變數

模式1

命令表1

;;

模式2

命令表2

;;

。。。。

*)                  # *表示其他所有

命令表n

;;

esac

例如:

case $1 in

file1)

echo “file1”

;;

file2)

echo “file2”

;;

*

echo “others”

;;

esac

迴圈語句

for...do...done

當迴圈次數已知或者確定時,使用for迴圈語句來多次執行一條或一組命令,迴圈體由dodone來限定

for  變數名  in  單詞表

do

命令表

done

說明:變數依次取單詞表中的各個單詞,每取依次單詞,就執行一次迴圈體,迴圈次數為單詞表中的單詞個數,命令表中可以是一條或由分號隔開的多條命令

如果單詞表是命令列上的所有位置引數時,可以省去  in  單詞表

list=`ls`

for file in $list

do

if[ $1 = $file ]

then

echo “$file found”;

    exit; #退出shell指令碼

fi

done

while...do...done

語法結構:

while  命令或表示式

do

命令表

done

說明:while首先測試其後的命令或表示式的值,如果為真,就執行一次迴圈體中的命令,然後再測試該命令或表示式的值,執行迴圈體,知道為假,退出迴圈

until...do...done

語法結構:

until 命令或表示式

do

命令表

done

與上面的相反

迴圈控制語句:

break  和  continue

break n   跳出n

continue 馬上跳轉到最近一層迴圈的下一輪迴圈

continue  n  轉到最近n層迴圈語句的下一輪迴圈上

shell函式

shell程式中,常把完成固定功能且多次使用的一組命令封裝在一個函式中,每當要使用時,呼叫函式名即可

函式呼叫前必須先定義,即順序上先定義函式,再呼叫

呼叫程式可以傳遞引數給函式,函式可以用return語句把執行結果返回呼叫程式

函式只在當前shell中起作用,不能輸出到子shell

shell函式定義格式

function funtion_name ()   #function可以省掉

{

...

}

函式呼叫方式

value_name = `function_name [arg1 arg2 ...]`    #函式結果返回給變數

function_name [arg1 arg2 ...]

echo $?           #獲取函式返回的狀態

函式變數的作用域

全域性作用域:在指令碼的其他地方都可以訪問該變數

區域性作用域:只能在宣告的作用域內訪問

區域性變數的宣告: Local  variable_name = value

指令碼除錯:

跟蹤指令碼執行結果:

在希望開始除錯的地方插入 set -x

在希望結束除錯的地方插入 set +x

---------------------------------------------------------------------

---------------------------------------------------------------------

Bash shell結構

1shbang行:指令碼的第一行,告之核心用哪個shell解釋shell指令碼,由#!shell完整路徑組成

2:註釋:#後面的為註釋,可以在一行後

3shell萬用字元元字元:shell中字元意義比較特殊,如? [] > < 2> >> |等,防止這些字元被解釋,則必須引用他們

4區域性變數:區域性變數作用域在本shell

5全域性變數:又稱為環境變數,由內建的export命令建立,作用域在本shell及子shell

6:提取變數值:$

7:引數:可以從命令列傳遞引數給指令碼

8:命令替換:`A` $(A)  結果可以賦給一個變數或代替所在位置

---------------------------------------------------------------------

正則表示式

正則表示式是一種字元模式,在查詢過程中匹配指定的字元,可以用特殊的元字元來控制它們,正則表示式都被置於兩個正斜槓//之間

元字元:表達的是不同於字元本身的含義

本書中的元字元兩類shell元字元、正則表示式元字元,它們各司其職,shell元字元是由shell解析的,就是下面所講的檔名置換;正則表示式元字元是由各種執行模式操作的程式來解析的,如vigrepsedawk

---------------------------------------------------------------------

正則表示式元字元:

^  行首定位

$  行尾定位

.  匹配單個字元

*  匹配0或多個重複的位於*前的字元

[]  匹配指定組字元中的任意一個 ;如[LlT]

[-] 匹配指定範圍內的字元 ;如[x-yA-Z0-8]

[^] 匹配不在指定組內的字元

[^ - ]跟上面的相反

\  轉移跟在後面的字元     #轉義元字元,使之不被解釋

\< 詞首定位符     #定位以什麼開頭的詞

\> 詞尾定位符     #定位以什麼結尾的詞

---------------------------------------------------------------------

grep 家族

grep家族由grepegrepfgrep組成 

grep命令在檔案全域性查詢指定的正則表示式,並列印所有包含該表示式的行

一般格式:grep  [選項]   基本正則表示式  [檔案  

選項:-n 顯示行號  -i 大小寫不敏感  -w表示式作為來查詢,也就是不是一個詞的一部分  -r 遞迴查詢

基本正則表示式:可為字串,如果為字串,最好用“”如果是模式匹配,用‘’呼叫變數時,也應該使用“”

檔案:可以為多個檔案;如 A1 A2

常用舉例

grep -n “your” www    #檔案www中查詢含有your單詞的行,且輸出行號

grep -nw “your” www    #檔案www中查詢含以your做單詞的行,且輸出行號

grep -nr ‘[a-zA-Z0-9].you’ ./  #遞迴./ 中查詢含有以a-z A-Z 0-9開始的單詞的行,且輸出行號

---------------------------------------------------------------------

find命令及xargs

find pathname -options [-print -exec -ok]

常用的optionsname 此時記住要用引號將檔名模式引起來

find ./  “*org.txt”   #在當前目錄及子目錄中尋找以org.txt結尾的檔案

find 找到檔案後可用xargs對其操作

find ./  “*org.txt” | xargs ls

find ./  “*org.txt” | xargs grep “device”  #在結果中搜索device

---------------------------------------------------------------------

啟動

系統啟動後

->init->getty程序

->/bin/login  初始化環境,啟動shell

->/bin/bash 執行/ect/profile,執行~/.bash_profile ~/.bash_login ~/.profile,執行~/.bashrc

->等待使用者輸入

---------------------------------------------------------------------

環境

一個程序的環境包括:變數等,它定義了可以從一個程序繼承到下一個程序的特性

使用者的shell配置定義在shell初始化檔案中,bash shell有許多啟動檔案,這些檔案可以執行source命令,對一個檔案執行source命令會使得這個檔案中的所有設定稱為當前shell的一部分,也就是說不會建立子shell

登陸時,會執行~/.bash_profile檔案執行source命令,如無,則source ~/.bash_login,若無,則source ~/.profile,這三個檔案只能source一個,再source ~/.bashrc

~/.bashrc:包含特定的變數和別名,當一個新的bash shell啟動或bash指令碼啟動時會自動執行source ~/.bashrc

在當前提示符下輸入shellbash啟動的是子shell

/etc/bashrc:系統級的函式和別名可以在/etc/bashrc檔案中設定,主提示符一般在這設定

~/.profile是一個使用者定義的初始化檔案,它是被Bourne shell使用的,因此不能包括對bash shell的特定設定,執行bash時只有沒找到其他檔案時才source此檔案,它允許使用者定製和修改shell環境,也可以放應用程式的初始化

---------------------------------------------------------------------

source命令或dot命令(.)  和  ./命令

source命令式內建的bash命令,來自C shell

dot命令也就是來自Bourne shell

二者完全一樣,都是一個指令碼名作為引數,shell將在當前的shell環境中執行這個指令碼,也就是不啟動子shell,指令碼中的設定的所有引數將成為當前shell環境的一部分。

./執行指令碼時是建立子shell,指令碼中的設定引數在指令碼退出後就無效了。

例子:在家目錄下的.bashrc中加入WANG=”ni hao”

然後. .bash.rc

此時執行內容為 echo “$WANG”的 指令碼

如用 ./sh.sh 則無輸出  #./執行時是在起一個子shell

如用source sh.sh或 . sh.sh則輸出ni hao  #source是在本shell中執行

---------------------------------------------------------------------

bash shell元字元(萬用字元)

\  按字面含義解釋後面的那個字元

&  在後臺處理的程序

; 分隔命令

$  替換命令

*  匹配任意字元

?  匹配任意單個字元

[...] 匹配[]中的任意一個字元

[!...] 不匹配[]!的任意一個字元

(cmds)  在子shell中執行命令

{cmds}  在當前shell中執行命令

---------------------------------------------------------------------

檔名置換

計算命令列時,shell會用元字元來縮寫能夠匹配某個特定字元組的檔名路徑名

將元字元展開為檔名或路徑名的過程稱為檔名替換或globbing

*    匹配檔案(夾)名中的任意字串

如:ls app*

cd cmdd*

?    匹配檔案(夾)名中的任意一個字元

[...] 匹配[]中的任意一個字元

[!...] 不匹配[]!的任意一個字元

如:ls [a-z]*.o   #匹配以a-z開頭的已.o結尾的檔案

ls [!0-9]*.o     #匹配以非0-9開頭的已.o結尾的檔案

---------------------------------------------------------------------

命令執行順序

命令1 && 命令2  #命令1執行成功才會執行命令2

命令1 || 命令2  #命令1執行不成功才會執行命令2

用() 和 {}將命令結合在一起

---------------------------------------------------------------------

Bash shell變數

變數可分為兩種:區域性變數環境變數

區域性變數只在建立他們的shell中可用,環境變數作用域可以擴充套件shell中去

變數命名規則:可以是字母、0-9、下劃線組成,必須以字母或下劃線開頭,其他字元都標誌著變數名的終止,變數名大小寫敏感

有兩個內建命令可以用來建立變數,他們是declaretypset,其選項可以控制變數的設定方式,建議使用declare.

格式:declare  [選項]  變數=

選項:-x  將變數設定成環境變數

      -r 將變數設定成只讀變數

      -a 將變數當一個陣列

---------------------------------------------------------------------

建立區域性變數

1:變數賦值:變數=    #注意等號周圍不能有任何空白字元,如果想賦空,可以在等號後跟上換行符

2:內建命令declare  變數=  #注意等號周圍不能有任何空白字元,如果想賦空,可以在等號後跟上換行符

例子:

設定:round=world 或 round=”world nice”  #“”保護空白符

設定:declare round=world

輸出:echo $round

設定:file.bak=”xxxx”   錯,變數名中出現非法字元

local函式:函式內建立區域性變數可以用local函式

---------------------------------------------------------------------

建立環境變數

環境變數,又被稱為全域性變數,作用域可以擴充套件到子shell中,通常環境變數用大寫

環境變數是已經用export內建命令匯出的變數,如果想設定環境變數,只需在設定變數時或賦值後使用export命令即可,declare -x也是設定環境變數

設定環境變數:

1export 變數=  #注意等號周圍不能有任何空白字元,如果想賦空,可以在等號後跟上換行符

2變數=; export 變數    #注意等號周圍不能有任何空白字元,如果想賦空,可以在等號後跟上換行符  

3declare -x 變數=  #注意等號周圍不能有任何空白字元,如果想賦空,可以在等號後跟上換行符

---------------------------------------------------------------------

設定只讀變數

只讀變數是不能被重新定義或復位的特殊變數,是如果使用declare定義的變數,可以重定義,不能復位

設定:name=”TOM”

readonly name   #設定只讀

unset name  #不能復位

name=Jem  #不能重定義

設定:declare -r city=”shanghai”

unset city #不能復位

declare city=beijin” #可以

---------------------------------------------------------------------

提取變數的值

在變數前加$

---------------------------------------------------------------------

復位變數

只要不被設定只讀,區域性變數和環境變數都可以用unset命令復位

格式:unset 變數名

---------------------------------------------------------------------

顯示變數值

1echo [選項]  變數   #echo將他的引數顯示到標準輸出

選項:-e   #允許解釋轉義字元,如echo -e “\a”  \a轉義為報警

如:echo The name is $NAME

echo -e “\a”  #報警

2printf命令

---------------------------------------------------------------------

變數擴充套件修飾符

可以用一些專用修飾符來測試修改變數,修飾符首先進行簡單的條件測試,檢查某變數是否已被設定,然後根據測試結果給變數賦值

${VA:-word}  #如變數VA已經設定且非空,則代入其值,否則代入word   臨時替換預設值 

${VA:=word}  #如變數VA已經設定且非空,則代入其值,否則VA設定為word,代入VA永久替換預設值

${VA:+word}  #如變數VA已經設定且非空,則代入word,否則代入空值   臨時替換預設值

${VA:?word}  #如變數VA已經設定且非空,則代入其值,否則輸出word且從shell退出  基於預設值建立錯誤資訊

注:不加冒號時,值為空也被認為已經設定

如:echo ${name-Joe}  #結果為空

echo ${name:-Joe}  #結果為Joe

echo ${namex:?”namex is undefined”}  

echo ${y?}  #如果y未設定,否則輸出parameter null or not set

${VA:offset}  #獲取變數VA值中位置從offset開始的字串

${VA:offset:length}  #獲取變數VA值中位置從offset開始長度length的字串  建立字串

如:var=notebook

echo ${var:0:4}   #結果note

---------------------------------------------------------------------

子串的變數擴充套件

模式匹配變數用來在串首或串尾截掉串的一部分,常用語刪除路徑名的頭或尾

${變數%模式}  #將變數值的尾部與模式進行最小匹配,並將匹配到的部分刪除

${變數%%模式} #將變數值的尾部與模式進行最大匹配,並將匹配到的部分刪除

${變數#模式}  #將變數值的頭部與模式進行最小匹配,並將匹配到的部分刪除

${變數##模式} #將變數值的頭部與模式進行最大匹配,並將匹配到的部分刪除

${#變數}      #替換為變數中的字元個數,如果是*,長度則是位置參量的個數

如:

pathname=”/usr/bin/local/bin”

echo ${pathname%/bin*}  #結果/usr/bin/local/

echo ${pathname%%/bin*}  #結果/usr

echo ${pathname#/usr}  #結果/bin/local/bin

echo ${pathname##/usr}  #結果bin

echo ${#pathname}  #結果8

---------------------------------------------------------------------

位置參量

下面這組專用內建變數常稱為位置參量,通常被shell指令碼用來從命令列接受引數,或被函式用來儲存傳遞給它的引數

$0  #指當前shell指令碼的名稱

$1-$9  #代表第一個到第9個位置參量

${10} ${11} #1011個位置參量,不用$10,$11

$#  其值為位置參量的個數,不含$0

$*  其值為所有的位置參量

[email protected]  同$*

“$*”  其值為“$1 $2 $3

[email protected]”  其值為“$1”“$2”“$3

位置引數可以用set命令來設定、重置或復位

set --   #清除所有的位置引數

---------------------------------------------------------------------

其他特殊變數

$    #當前shellpid

_    #當前sh的選項設定

?    #已執行上一條命令的退出值

!    #最後一個進入後臺的作用的pid

---------------------------------------------------------------------

引用

用來保護特殊的元字元不被解釋禁止參量擴充套件

引用有三種方式:反斜槓單引號雙引號

需要引用的特殊元字元有:

;

&

()

{}

|

< > 

空格 tab 換行符

* [] ? 

1:單引號和雙引號必須成對出現

2:單引號保護特殊元字元免受解釋,雙引號也能,但雙引號允許處理變數替換字元$和命令替換字元``\

3:雙引號可以保護單引號,單引號可以保護雙引號

4:如果有不匹配的引號,bash會出現次提示符

反斜槓:反斜槓用於引用(或轉義)單個字元,使其免受解釋。

單引號中的反斜槓不會被解釋

如果在雙引號中,反斜槓將保護$ ``和反斜槓免受解釋

單引號:成對出現,保護所有元字元不被解釋,列印雙引號就必須用雙引號將其括起來,或反斜槓轉義

雙引號:同單引號,但是允許進行變數替換$和命令替換``\

簡言之:單引號中什麼都不被解釋。雙引號中$ `` \這三個會被解釋,如不想解釋用\轉義

注意:``$()是一樣的,所以$(date)也會展開

---------------------------------------------------------------------

命令替換

命令替換的用處是將命令的輸出結果賦給一個變數或將命令的輸出結果代入命令所在位置

bash 允許使用兩種格式:`命令  和  $(命令)

執行擴充套件時,bash先執行命令,然後返回命令的標準輸出,輸出結果末尾的換行符都將被刪除,如果不想刪除,可用“”括起,如:echo $(cal)

如:echo “this is `date +%H`”   #this is 09

d=$(date)  #d存放命令date的結果

`命令`  \保留字面意思,除非後面跟$ ` \ ``$  \生效,可用\轉義之,``中再有``的話必須用\轉義

$(命令)  中的所有特殊字元不會解釋

命令替換可以被巢狀``必須使用\`轉義,如echo `basename \`pwd\` `  #其中轉義後的`pwd`也是當做命令替換的,如:$(basename $(pwd))

---------------------------------------------------------------------

陣列

bash 中可以建立一維陣列,陣列允許將一列詞放到一個變數名中,可以用內建命令declare -a建立,或直接給變數名一個下標來建立,如x[0]=5   索引值為從0開始的整數,陣列無上限,索引也不必是有序數<