Shell指令碼簡單總結及編寫指令碼中的小技巧

來源:互聯網
上載者:User

主要從以下幾個方面進行bash入門級的總結:

1、命令曆史、命令補全

2、管道、重新導向

3、命令別名和命令替換

4、命令列編輯

5、檔案名稱通配

6、Bash的相關設定檔及變數

7、編程(條件判斷、迴圈控制)

8、bash中的數組

9、shell編程技巧和編程規範

 

 

1、命令曆史、命令補全

 

查看命令曆史:history

-c:清空命令曆史

-d OFFSET [n]: 刪除指定位置的命令

-w:儲存命令曆史至曆史檔案中,這對於經常在不同的終端上執行命令很有用

 

命令曆史的提示:

!n:執行命令曆史中的第n條命令;

!-n:執行命令曆史中的倒數第n條命令;

!!: 執行上一條命令;

!string:執行命令曆史中最近一個以指定字串開頭的命令

!$:引用前一個命令的最後一個參數;

Esc, .

Alt+.

 

命令補全,路徑補全

命令補全:搜尋PATH環境變數所指定的每個路徑下以我們給出的字串開頭的可執行檔,如果多於一個,兩次tab,可以給出列表;否則將直接補全;

路徑補全:搜尋我們給出的起始路徑下的每個檔案名稱,並試圖補全;

 

 

2、管道、重新導向

 

管道------前一個命令的輸出,作為後一個命令的輸入

命令1 | 命令2 | 命令3 | ...

如:cat /var/log/message |less

   find ./ -name ex* | xargs mv /backup

 

> 覆蓋輸出

>> 追加輸出

2> 重新導向錯誤輸出

2>> 追加方式

&> 重新導向標準輸出或錯誤輸出至同一個檔案

< 輸入重新導向

<< Here Document

:> file 清空一個檔案

 

對於Here Document舉個執行個體:

cat >> /etc/hosts << EOF

172.28.9.45www01.opsmysql.com

172.28.9.46www02.opsmysql.com

172.28.9.47www03.opsmysql.com

172.28.9.48www04.opsmysql.com

EOF

 

"*/5 * * * * /usr/sbin/ntpdate ntp.api.bz > /dev/null 2>&1

/dev/null 2>&1 : 意思是將標準輸出和錯誤輸出全部重新導向到/dev/null中

 

 

3、命令別名和命令替換

命令別名

alias CMDALIAS='COMMAND [options] [arguments]'

在shell中定義的別名僅在當前shell生命週期中有效;別名的有效範圍僅為當前shell進程;

 

ualias CMDALIAS

 

對於我們設定別名的命令,如果要使用沒有設定別名時的命令格式,即預設格式可以在命令前面加上: \

\CMD

 

對於別名我們還可以寫在設定檔中:

全域設定檔:/etc/bashrc

使用者設定檔:~/.bashrc

 

命令替換: $(COMMAND), 反引號:`COMMAND`

把命令中某個子命令替換為其執行結果的過程

如:

echo "The date time is : `date`"

echo "The date time is : $(date +%F)"

 

bash支援的引號:

``: 命令替換

"": 弱引用,可以實現變數替換

'': 強引用,不完成變數替換

 

4、命令列編輯

游標跳轉:

Ctrl+a:跳到命令列首

Ctrl+e:跳到命令列尾

Ctrl+u: 刪除游標至命令列首的內容

Ctrl+k: 刪除游標至命令列尾的內容

Ctrl+l: 清屏

 

5、檔案名稱通配:globbing

 

*: 任意長度的任一字元

?:任意單個字元

[]:匹配指定範圍內的任意單個字元

[abc], [a-m], [a-z], [A-Z], [0-9], [a-zA-Z], [0-9a-zA-Z]

[:space:]:空白字元

[:punct:]:標點符號

[:lower:]:小寫字母

[:upper:]: 大寫字母

[:alpha:]: 大小寫字母

[:digit:]: 數字

[:alnum:]: 數字和大小寫字母

 

# man 7 glob

[^]: 匹配指定範圍之外的任意單個字元

 

[[:alpha:]]*[[:space:]]*[^[:alpha:]]

 

6、Bash相關設定檔及變數

 

bash的設定檔:

全域配置

/etc/profile, /etc/profile.d/*.sh, /etc/bashrc

個人配置

~/.bash_profile, ~/.bashrc

 

profile類的檔案:

設定環境變數

運行命令或指令碼

 

bashrc類的檔案:

設定本地變數

定義命令別名

 

登入式shell如何讀取設定檔?

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

 

非登入式shell如何設定檔?

~/.bashrc --> /etc/basrc --> /etc/profile.d/*.sh

 

關於環境變數命令介紹:

1.echo 顯示某個環境變數值 echo $PATH

2.export 設定一個新的環境變數 export HELLO="hello" (可以無引號)

3.env 顯示所有環境變數

4.set 顯示本地定義的shell變數

5.unset 清除環境變數 unset HELLO

6.readonly 設定唯讀環境變數 readonly HELLO

 

常見的環境變數

PATH:決定了shell將到哪些目錄中尋找命令或程式  

HOME:目前使用者主目錄

MAIL:是指目前使用者的郵件存放目錄

SHELL:是指目前使用者用的是哪種Shell

HISTSIZE:是指儲存曆史命令記錄的條數

LOGNAME:是指目前使用者的登入名稱

HOSTNAME:是指主機的名稱,許多應用程式如果要用到主機名稱的話,通常是從這個環境變數中來取得的

LANG/LANGUGE:是和語言相關的環境變數,使用多種語言的使用者可以修改此環境變數

PS1:是基本提示符,對於root使用者是#,對於普通使用者是$

PS2:是附屬提示符,預設是“>”。可以通過修改此環境變數來修改當前的命令符

 

 

位置變數:

$1, $2, ...$n

 

特殊變數:

$?:上一個命令的執行狀態傳回值,echo $0結果如果為0表示成功,非0表示失敗.

$0:擷取當前執行的shell指令碼的檔案名稱,通常結合basename使用

$*:擷取當前shell的所有參數,$1 $2 $3 ,注意與$#的區別

$#:擷取當前shell命令列中參數的總個數

$$:擷取當前shell的進程號(PID)

$!:執行上一個指令的PID

$@:這個程式的所有參數 "$1" "$2" "$3" "…"

 

注意:有時候變數名很容易與其他文字混淆,比如我們在某個變數的值後面追加內容:

num=2

echo "this is the $numnd"

這並不會列印出"this is the 2nd",而僅僅列印"this is the ",因為shell會去搜尋變數numnd的值,但是這個變數時沒有值的。可以使用花括弧來告訴shell我們要列印的是num變數:

num=2

echo "this is the ${num}nd"

這將列印: this is the 2nd

 

變數名不能以數字開頭!!!!!!!!!!!!!!!!

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++

shell中如何進行算術運算:

A=3

B=6

1).let 算術運算運算式

let C=$A+$B

2).$[算術運算運算式]

C=$[$A+$B]

3).$((算術運算運算式))

C=$(($A+$B))

4).expr 算術運算運算式,運算式中各運算元及運算子之間要有空格,而且要使用命令引用

C=`expr $A + $B`

 

這些計算方法都是shell編程的基礎!!!

 

 

shell中關於字串的簡單操作:

取字串長度

A="admin"

echo ${$A} 或 expr length $A

 

字串的替換與刪除操作:

${變數#關鍵字}--------->若變數內容從頭開始的資料符合‘關鍵字’,則將符合的最短資料刪除

如:echo

 

${變數##關鍵字}--------->若變數內容從頭開始的資料符合‘關鍵字’,則將符合的最長資料刪除

 

${變數%關鍵字}--------->若變數內容從尾向前的資料符合‘關鍵字’,則將符合的最短資料刪

 

${變數%%關鍵字}--------->若變數內容從尾向前的資料符合‘關鍵字’,則將符合的最長資料刪除

 

${變數/舊字串/新字串}--------->若變數內容符合‘舊字串’則‘第一箇舊字串會被新字串取代

 

${變數//舊字串/新字串}--------->若變數內容符合‘舊字串’則‘全部的舊字串會被新字串取代

 

 

7、編程(條件判斷、迴圈控制)

 

下面總結下條件測試類型

整數測試

字元測試

檔案測試

 

條件測試的運算式:

[ expression ]

[[ expression ]]  -----在Bash高版本中基本上只能用這個進階的了...上面那個會報錯!

test expression

 

整數比較:

-eq: 測試兩個整數是否相等;比如 $A -eq $B

-ne: 測試兩個整數是否不等;不等,為真;相等,為假;

-gt: 測試一個數是否大於另一個數;大於,為真;否則,為假;

-lt: 測試一個數是否小於另一個數;小於,為真;否則,為假;

-ge: 大於或等於

-le:小於或等於

 

間邏輯關係:

邏輯與: &&

第一個條件為假時,第二條件不用再判斷,最終結果已經有;

第一個條件為真時,第二條件必須得判斷;

邏輯或: ||

 

注意:[ 條件1 -a 條件2 ]  等價於 [ 條件1 ] && [ 條件2 ]

 

還有一點要注意:

可以

[[ 條件1 && 條件2 ]]這樣使用

不可以

[ 條件1 && 條件2 ]這樣使用

 

字元測試:

==:測試是否相等,相等為真,不等為假

!=: 測試是否不等,不等為真,等為假

\>

\<

-n string: 測試指定字串是否為空白,空則真,不空則假

-z string: 測試指定字串是否不空,不空為真,空則為假

string =""  字串為空白

string !="" 字串不為空白

 

 

檔案測試:

-e FILE:測試檔案是否存在

-f FILE: 測試檔案是否為普通檔案

-d FILE: 測試指定路徑是否為目錄

-s FILE: 判斷檔案是否存在且大小大於0

-r FILE: 測試目前使用者對指定檔案是否有讀取許可權

-w FILE: 檔案是否可寫

-x FILE: 檔案是否可執行

 

 

再簡單說下指令碼退出狀態代碼

 

exit: 退出指令碼

exit #

如果指令碼沒有明確定義退出狀態代碼,那麼,最後執行的一條命令的退出碼即為指令碼的退出狀態代碼;

通常:

# 是 0 表示正常退出

# 非 0 表示錯誤退出

 

+++++++++++++++++++++++++++++++++++++++++++++++++

條件判斷--if

單分支if語句

if 判斷條件; then

 statement1

 statement2

 ...

fi

 

雙分支的if語句:

if 判斷條件; then

statement1

statement2

...

else

statement3

statement4

...

fi

 

多分支的if語句:

if 判斷條件1; then

 statement1

 ...

elif 判斷條件2; then

 statement2

 ...

elif 判斷條件3; then

 statement3

 ...

else

 statement4

 ...

fi

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

選擇結構--case

case SWITCH in

value1)

 statement

 ...

 ;;

value2)

 statement

 ...

 ;;

*)

 statement

 ...

 ;;

esac

 

 

說明:value1) 是Regex樣式,可以用下面字元:

* 任意長度的字串

C* 表示以C字元開頭的字串

? 任意單個字元,???? 表示4個字元的字串

[abc] a, b, 或c三字元其中之一,如:[abc]123,匹配a123或b123或c123。

[a-n] 從a到n的任一字元

| 多重選取,分隔字元

 

+++++++++++++++++++++++++++++++++++++++++++++

迴圈控制---for

兩種用法:

for 變數 in 列表; do

迴圈體

done

 

for (( expr1 ; expr2 ; expr3 )); do

迴圈體

done

 

 

迴圈控制---while

while CONDITION; do

statment

done

進入迴圈:條件滿足

退出迴圈:條件不滿足

 

while的特殊用法一(死迴圈):

while :; do

statment

done

 

while的特殊用法二(從某個檔案中讀取行):

while read LINE; do

statment

done < /PATH/TO/SOMEFILE

 

方法二另外一種寫法:

cat ip.txt | while read line

do

echo $line

done

 

迴圈控制---until

until跟while相反,可參照while

until CONDITION; do

statement

...

done

 

判斷條件是否成立,不成立就執行迴圈體,成立就退出!

 

 

迴圈控制語句

break

中斷迴圈,而後執行迴圈後面的語句;預設是跳出一層迴圈,如果要跳出多層迴圈,可以用 break n(n是大於1的數字,也就次數)。

continue

中斷當前這一次迴圈,提前進入下一次迴圈,預設跳過一層迴圈,如果要跳過多層迴圈,可以用 continue n(n是大於1的數字,也就次數)。

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++

select (產生菜單選擇)

select 運算式是一種bash的擴充應用,尤其擅長於互動式使用,使用者可以從一組不同的值中進行選擇.

select 命令可以建立簡單的列表,結構類似for迴圈,一般與case語句結合使用。

下面寫一個執行個體:

#!/bin/bash

echo "What is your favourite OS?"

select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do

break

done

echo "You have selected $var"

 

 

8、bash中的數組使用

數組賦值方式:

(1) array=(var1 var2 var3 ... varN)  

(2) array=([0]=var1 [1]=var2 [2]=var3 ... [n]=varN)  

(3) array[0]=var1      

   arrya[1]=var2      

   ...      

   array[n]=varN

 

注意:shell中數組的下標預設是從0開始的!

 

擷取數組元素個數或者長度:

(1) ${#array[@]}      

(2) ${#array[*]}

 

 

顯示數組元素:

echo ${array[*]}  #顯示所有元素

echo ${array[@]}

echo ${array[@]:0}

 

echo ${array[0]}  #顯示第一個元素

 

echo ${array[@]:2} #不顯示數組中前兩個元素

echo ${array[@]:0:2}  #從第一個元素開始顯示兩個元素

 

 

刪除數組中的元素:

unset array[2] #刪除第三個元素

unset array    #刪除整個數組

 

 

子串刪除:

echo ${array[@]#t*e}  # 左邊開始最短的匹配:"t*e",這將匹配到"thre"

echo ${array[@]##t*e} # 左邊開始最長的匹配,這將匹配到"three"

echo ${array[@] %o}   # 從字串的結尾開始最短的匹配

echo ${array[@] %%o}  # 從字串的結尾開始最長的匹配

 

子串替換:

echo ${array[@] /o/m}  #第一個匹配到的,會被刪除

echo ${array[@] //o/m} #所有匹配到的,都會被刪除

echo ${array[@] //o/}  #沒有指定替換子串,則刪除匹配到的子符

echo ${array[@] /#o/k} #替換字串前端子串

echo ${array[@] /%o/k} #替換字串後端子串

 

 

迴圈列出數組元素:

#!/bin/bash

arr=(ab bc cd)

lenarr=${#arr[@]}

for (( i=0; i<$lenarr}; i++ )); do    

 echo ${arr[$i]}

done

 

 

#!/bin/bash

arr=(ab bc cd)

lenarr=${#arr[@]}

i=0

while [[ $i -lt $lenarr ]]

do

 echo ${arr[$i]}

 let i++

done

 

一個執行個體:

#!/bin/bash

# 設定IFS將分割符 設定為 分行符號(\n)  

OLDIFS=$IFS

IFS=$'\n'

 

# 讀取檔案內容到數組

fileArray=($(cat file.txt))      

 

# restore it  

IFS=$OLDIFS  

tLen=${#fileArray[@]}      

 

# 迴圈顯示檔案內容  

for (( i=0; i<${tLen}; i++ )); do    

 echo "${fileArray[$i]}"  

done

 

 

9、shell編程技巧和編程規範

 

檢測文法相關:bash -n 指令碼名

命令追蹤:bash -x 指令碼名

 

shell輸入和輸出中:

read 用法

cat 特殊用法

echo 特殊用法

 

後台執行命令:& nohup

如果正在運行一個進程,而且覺得在退出帳戶時該進程還不會結束,那麼可以使用nohup命令。該命令可以在你退出帳戶之後繼續運行相應的進程。Nohup就是不掛起的意思( no hang up)。

nohup命令的一般形式為nohup command &

shift 用法

.......

.........

..........

後面略!

簡單說下編程規範:

1.檔案注釋說明

在編寫的每個指令檔中,應當包含檔案注釋、指令碼用途簡單描述、版本、作者等...如:

 

#!/bin/bash

#Description: .......

#Date: xxxx-xx-xx

#Version: ....

#Author: Andy

 

2.代碼注釋

3.函數注釋--說明該函數的功能

 

4.變數命名正常化

取名要說明這個變數代表的含義

變數名或函數名不要太長

名稱盡量使用大寫或大寫開頭

如:

Passwd

Num_Count

 

5.代碼注意縮排

 

 原創作品,允許轉載,轉載時請務必以超連結形式標明文章 原始出處 、作者資訊和本聲明。否則將追究法律責任。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.