【APP】Shell腳本簡單總結及編寫腳本中的小技巧

主要從以下幾個方面進行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) 是正則表達式樣式,可以用下面字符:

* 任意長度的字符串

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.代碼注意縮進


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章