Linux shell腳本基礎學習詳細介紹(完整版)二

詳細介紹Linux shell腳本基礎學習(五) Linux shell腳本基礎前面咱們在介紹Linux shell腳本的控制流程時,還有一部份內容沒講就是有關here document的內容這裏繼續。 
Linux shell腳本基礎已經被分紅好幾個部分了,這裏對控制流程的內容也就立刻講完了,這是最後一部分關於here document,這裏舉例稍微有點複雜,咱們慢慢來分析這個複雜Linux shell腳本。html

 

6. Here documents程序員

當要將幾行文字傳遞給一個命令時,here documents(譯者注:目前尚未見到過對該詞適合的翻譯)一種不錯的方法。對每一個腳本寫一段幫助性的文字是頗有用的,此時若是咱們四有那個 here documents就沒必要用echo函數一行行輸出。 一個 "Here document" 以 << 開頭,後面接上一個字符串,這個字符串還必須出如今here document的末尾。下面是一個例子,在該例子中,咱們對多個文件進行重命名,而且使用here documents打印幫助:算法

#!/bin/shshell

# we have less than 3 arguments. Print the help text:express

if [ $# -lt 3 ] ; then編程

cat <vim

ren -- renames a number of files using sed regular expressions框架

USAGE: ren 'regexp' 'replacement' files...less

EXAMPLE: rename all *.HTM files in *.html:ide

ren 'HTM$' 'html' *.HTM

HELP

exit 0

fi

OLD="$1"

NEW="$2"

# The shift command removes one argument from the list of

# command line arguments.

shift

shift

# $* contains now all the files:

for file in $*; do

if [ -f "$file" ] ; then

newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`

if [ -f "$newfile" ]; then

echo "ERROR: $newfile exists already"

else

echo "renaming $file to $newfile ..."

mv "$file" "$newfile"

fi

fi

done

這是一個複雜一些的例子。讓咱們詳細討論一下。第一個if表達式判斷輸入命令行參數是否小於3個 (特殊變量$# 表示包含參數的個數) 。若是輸入參數小於3個,則將幫助文字傳遞給cat命令,而後由cat命令將其打印在屏幕上。打印幫助文字後程序退出。若是輸入參數等於或大於3個,咱們 就將第一個參數賦值給變量OLD,第二個參數賦值給變量NEW。下一步,咱們使用shift命令將第一個和第二個參數從參數列表中刪除,這樣原來的第三個 參數就成爲參數列表$*的第一個參數。而後咱們開始循環,命令行參數列表被一個接一個地被賦值給變量$file。接着咱們判斷該文件是否存在,若是存在則 經過sed命令搜索和替換來產生新的文件名。而後將反短斜線內命令結果賦值給newfile。這樣咱們就達到了咱們的目的:獲得了舊文件名和新文件名。然 後使用mv命令進行重命名。這樣就明瞭這個複雜的Linux shell腳本了吧。

詳細介紹Linux shell腳本基礎學習(六) Linux shell腳本基礎學習咱們這裏就差很少講完了,最後一部份內容是關於函數的,這就差很少把基礎部分介紹完了,後面還會有實例。 

4)函數

若是您寫了一些稍微複雜一些的程序,您就會發如今程序中可能在幾個地方使用了相同的代碼,而且您也會發現,若是咱們使用了函數,會方便不少。一個函數是這個樣子的:

functionname()

{

# inside the body $1 is the first argument given to the function

# $2 the second ...

body

}

您須要在每一個程序的開始對函數進行聲明。

下面是一個叫作xtitlebar的腳本,使用這個腳本您能夠改變終端窗口的名稱。

這裏使用了一個叫作help的函數。正如您能夠看到的那樣,這個定義的函數被使用了兩次。

#!/bin/sh

# vim: set sw=4 ts=4 et:

help()

{

cat <

xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole

USAGE: xtitlebar [-h] "string_for_titelbar"

OPTIONS: -h help text

EXAMPLE: xtitlebar "cvs"

HELP

exit 0

}

# in case of error or if -h is given we call the function help:

[ -z "$1" ] && help

[ "$1" = "-h" ] && help

# send the escape sequence to change the xterm titelbar:

echo -e "33]0;$107"

#

在腳本中提供幫助是一種很好的編程習慣,這樣方便其餘用戶(和您)使用和理解腳本。

命令行參數

咱們已經見過$* 和 $1, $2 ... $9 等特殊變量,這些特殊變量包含了用戶從命令行輸入的參數。迄今爲止,咱們僅僅瞭解了一些簡單的命令行語法(好比一些強制性的參數和查看幫助的-h選項)。 可是在編寫更復雜的程序時,您可能會發現您須要更多的自定義的選項。一般的慣例是在全部可選的參數以前加一個減號,後面再加上參數值 (好比文件名)

有好多方法能夠實現對輸入參數的分析,可是下面的使用case表達式的例子無遺是一個不錯的方法。

#!/bin/sh

help()

{

cat <

This is a generic command line parser demo.

USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2

HELP

exit 0

}

while [ -n "$1" ]; do

case $1 in

-h) help;shift 1;; # function help is called

-f) opt_f=1;shift 1;; # variable opt_f is set

-l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2

--) shift;break;; # end of options

-*) echo "error: no such option $1. -h for help";exit 1;;

*) break;;

esac

done

echo "opt_f is $opt_f"

echo "opt_l is $opt_l"

echo "first arg is $1"

echo "2nd arg is $2"

您能夠這樣運行該腳本:

cmdparser -l hello -f -- -somefile1 somefile2

返回的結果是:

opt_f is 1

opt_l is hello

first arg is -somefile1

2nd arg is somefile2

這個腳本是如何工做的呢?腳本首先在全部輸入命令行參數中進行循環,將輸入參數與case表達式進行比較,若是匹配則設置一個變量而且移除該參數。根據unix系統的慣例,首先輸入的應該是包含減號的參數。

詳細介紹Linux shell腳本基礎學習(七) Linux shell腳本基礎的學習理論知識已經講完了,後面是兩個具體的實例,這裏先說第一個關於二進制什麼時候禁止之間的轉換。 
Linux shell腳本基礎學習這部分若是隻看前面間的理論部分雖然有一些例子,可是還不夠系統,這裏將以具體實例給你們展示Linux shell腳本編程,以幫助你們完善Linux shell基礎的學習和提升。
第2部分 實例
如今咱們來討論編寫一個腳本的通常步驟。任何優秀的腳本都應該具備幫助和輸入參數。而且寫一個僞腳本(framework.sh),該腳本包含了大多數腳本都須要的框架結構,是一個很是不錯的主意。這時候,在寫一個新的腳本時咱們只須要執行一下copy命令:
cp framework.sh myscript
而後再插入本身的函數。
讓咱們再看個例子:
二進制到十進制的轉換
腳本 b2d 將二進制數 (好比 1101) 轉換爲相應的十進制數。這也是一個用expr命令進行數學運算的例子:

複製代碼 代碼以下:
#!/bin/sh # vim: set sw=4 ts=4 et:
help() { cat < b2h -- convert binary to decimal USAGE: b2h [-h] binarynum OPTIONS: -h help text EXAMPLE: b2h 111010 will return 58 HELP exit 0 } error() { # print an error and exit echo "$1" exit 1 } lastchar() { # return the last character of a string in $rval if [ -z "$1" ]; then # empty string
rval="" return fi # wc puts some space behind the output this is why we need sed: numofchar=`echo -n "$1" | wc -c | sed 's/ //g' ` # now cut out the last char rval=`echo -n "$1" | cut -b $numofchar` }
chop() { # remove the last character in string and return it in $rval if [ -z "$1" ]; then # empty string rval="" return fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g' ` if [ "$numofchar" = "1" ]; then # only one char in string rval="" return fi
numofcharminus1=`expr $numofchar "-" 1` # now cut all but the last char:
rval=`echo -n "$1" | cut -b 0-${numofcharminus1}` } while [ -n "$1" ]; do case $1 in -h) help;shift 1;; # function help is called --) shift;break;; # end of options -*) error "error: no such option $1. -h for help";; *) break;; esac done # The main program sum=0
weight=1 # one arg must be given: [ -z "$1" ] && help
binnum="$1" binnumorig="$1" while [ -n "$binnum" ]; do lastchar "$binnum" if [ "$rval" = "1" ]; then sum=`expr "$weight" "+" "$sum"`
fi # remove the last position in $binnum chop "$binnum"
binnum="$rval" weight=`expr "$weight" "*" 2` done echo "binary $binnumorig is decimal $sum"

該腳本使用的算法是利用十進制和二進制數權值 (1,2,4,8,16,..),好比二進制"10"能夠這樣轉換成十進制:
0 * 1 + 1 * 2 = 2
爲了獲得單個的二進制數咱們是用了lastchar 函數。該函數使用wc –c計算字符個數,而後使用cut命令取出末尾一個字符。Chop函數的功能則是移除最後一個字符。
這個Linux shell腳本實例幫咱們完成了轉換,下一次咱們將舉例一個文件循環程序。 
詳細介紹Linux shell腳本基礎學習(八)
Linux shell腳本基礎學習實例前面說明了十進制和二進制的轉換,這裏舉最後一個例子,關於文件的循環,同時也說明一下如何調試,來結束咱們的課程。 

 

Linux shell腳本前面的實例是說明十進制和二進制的轉換,還以一個有關文件循環的實例來結束這部份內容的學習。相信Linux shell腳本的基礎學習的學習者應該可以掌握一些簡單的Linux shell腳本的編寫。 文件循環程序

或許您是想將全部發出的郵件保存到一個文件中的人們中的一員,可是在過了幾個月之後,這個文件可能會變得很大以致於使對該文件的訪問速度變慢。下面的 腳本rotatefile可 以解決這個問題。這個腳本能夠重命名郵件保存文件(假設爲outmail)爲outmail.1,而對於 outmail.1就變成了outmail.2 等等等等...

 

複製代碼 代碼以下:
#!/bin/sh # vim: set sw=4 ts=4 et: ver="0.1" help() { cat < rotatefile -- rotate the file name USAGE: rotatefile [-h] filename OPTIONS: -h help text EXAMPLE: rotatefile out This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1 and create an empty out-file The max number is 10 version $ver HELP exit 0 } error() { echo "$1" exit 1 } while [ -n "$1" ]; do case $1 in -h) help;shift 1;; --) break;; -*) echo "error: no such option $1. -h for help";exit 1;; *) break;; esac done # input check: if [ -z "$1" ] ; then error "ERROR: you must specify a file, use -h for help" fi filen="$1" # rename any .1 , .2 etc file: for n in 9 8 7 6 5 4 3 2 1; do if [ -f "$filen.$n" ]; then p=`expr $n + 1` echo "mv $filen.$n $filen.$p" mv $filen.$n $filen.$p fi done # rename the original file: if [ -f "$filen" ]; then echo "mv $filen $filen.1" mv $filen $filen.1 fi echo touch $filen touch $filen

 

這個腳本是如何工做的呢?在檢測用戶提供了一個文件名之後,咱們進行一個9到1的循環。文件9被命名爲10,文件8重命名爲9等等。循環完成以後,咱們將原始文件命名爲文件1 同時創建一個與原始文件同名的空文件。

調試

最簡單的調試命令固然是使用echo命令。您可使用echo在任何懷疑出錯的地方打印任何變量值。這也是絕大多數的shell程序員要花費80%的時間來調試程序的緣由。Shell程序的 好處在於不須要從新編譯,插入一個echo命令也不須要多少時間。

shell也有一個真實的調試模式。若是在腳本"strangescript" 中有錯誤,您能夠這樣來進行調試:

sh -x strangescript

這將執行該腳本並顯示全部變量的值。

shell還有一個不須要執行腳本只是檢查語法的模式。能夠這樣使用:

sh -n your_script

這將返回全部語法錯誤

相關文章
相關標籤/搜索