?? linux_shell
字號:
1, for var in ....; do .... done 在下面的例子中,將分別打印ABC到屏幕上: #!/bin/sh for var in A B C ; do echo "var is $var" done 2, for (( 條件一; 條件二; 條件三 );do ... done 例: for ((i=1;i<10;i=$[$i+1]));do echo "a" done輸出:aaaaaaaaa條件一:這可以看成是『初始值』,如上面的例子中,初始值是 i=1 啦!條件二:這可以看成是『符合值』,如上面的例子中,當 i<=100 的時候都是符合條件的!條件三:這可以看成是『步階』!也就是說, i 每次都加一! 所以啦!上面的例子是說:由 i=1 開始到 i<= 100 ,每次 i 都加一來執(zhí)行底下的程序段(就是 s=s+i ),當 i >100 (也就是 i=101 )就跳出這一段程序段!怎樣!不難吧! 下面是一個更為有用的腳本showrpm,其功能是打印一些RPM包的統(tǒng)計信息: #!/bin/sh # list a content summary of a number of RPM packages # USAGE: showrpm rpmfile1 rpmfile2 ... # EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm for rpmpackage in $*; do if [ -r "$rpmpackage" ];then echo "=============== $rpmpackage ==============" rpm -qi -p $rpmpackage else echo "ERROR: cannot read file $rpmpackage" fi done 這里出現(xiàn)了第二個特殊的變量$*,該變量包含了所有輸入的命令行參數(shù)值。 如果您運行showrpm openssh.rpm w3m.rpm webgrep.rpm 此時 $* 包含了 3 個字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.『until:直到條件相同的時候才離開程序』;『while:當條件相同的時候,就繼續(xù)做!』 until [ condition1 ] && { || } [ condition2 ] ... 5. 引號 在向程序傳遞任何參數(shù)之前,程序會擴展通配符和變量。這里所謂擴展的意思是程序會把通配符(比如*)替換成合適的文件名,它變量替換成變量值。為了防止程序作這種替換,您可以使用引號:讓我們來看一個例子,假設在當前目錄下有一些文件,兩個jpg文件, mail.jpg 和tux.jpg。 編譯SHELL腳本 #ch#!/bin/sh mod +x filename cho *.jpg ./filename 來執(zhí)行您的腳本。 這將打印出"mail.jpg tux.jpg"的結果。 引號 (單引號和雙引號) 將防止這種通配符擴展: #!/bin/sh echo "*.jpg" echo '*.jpg' 這將打印"*.jpg" 兩次。 單引號更嚴格一些。它可以防止任何變量擴展。雙引號可以防止通配符擴展但允許變量擴展。 #!/bin/sh echo $SHELL echo "$SHELL" echo '$SHELL' 運行結果為: /bin/bash /bin/bash $SHELL 最后,還有一種防止這種擴展的方法,那就是使用轉義字符——反斜桿: echo *.jpg echo $SHELL 這將輸出: *.jpg $SHELL 6. Here documents 當要將幾行文字傳遞給一個命令時,here documents(譯者注:目前還沒有見到過對該詞適合的翻譯)一種不錯的方法。對每個腳本寫一段幫助性的文字是很有用的,此時如果我們四有那個 here documents就不必用echo函數(shù)一行行輸出。 一個 "Here document" 以 << 開頭,后面接上一個字符串,這個字符串還必須出現(xiàn)在here document的末尾。下面是一個例子,在該例子中,我們對多個文件進行重命名,并且使用here documents打印幫助: #!/bin/sh # we have less than 3 arguments. Print the help text: if [ $# -lt 3 ] ; then cat < ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp' 'replacement' files... EXAMPLE: rename all *.HTM files in *.html: 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表達式判斷輸入命令行參數(shù)是否小于3個 (特殊變量$# 表示包含參數(shù)的個數(shù)) 。如果輸入?yún)?shù)小于3個,則將幫助文字傳遞給cat命令,然后由cat命令將其打印在屏幕上。打印幫助文字后程序退出。如果輸入?yún)?shù)等于或大于3個,我們就將第一個參數(shù)賦值給變量OLD,第二個參數(shù)賦值給變量NEW。下一步,我們使用shift命令將第一個和第二個參數(shù)從參數(shù)列表中刪除,這樣原來的第三個參數(shù)就成為參數(shù)列表$*的第一個參數(shù)。然后我們開始循環(huán),命令行參數(shù)列表被一個接一個地被賦值給變量$file。接著我們判斷該文件是否存在,如果存在則通過sed命令搜索和替換來產(chǎn)生新的文件名。然后將反短斜線內(nèi)命令結果賦值給newfile。這樣我們就達到了我們的目的:得到了舊文件名和新文件名。然后使用mv命令進行重命名。 4)函數(shù) 如果您寫了一些稍微復雜一些的程序,您就會發(fā)現(xiàn)在程序中可能在幾個地方使用了相同的代碼,并且您也會發(fā)現(xiàn),如果我們使用了函數(shù),會方便很多。一個函數(shù)是這個樣子的: functionname() { # inside the body $1 is the first argument given to the function # $2 the second ... body } 您需要在每個程序的開始對函數(shù)進行聲明。 下面是一個叫做xtitlebar的腳本,使用這個腳本您可以改變終端窗口的名稱。 這里使用了一個叫做help的函數(shù)。正如您可以看到的那樣,這個定義的函數(shù)被使用了兩次。 #!/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" # 在腳本中提供幫助是一種很好的編程習慣,這樣方便其他用戶(和您)使用和理解腳本。 命令行參數(shù) 我們已經(jīng)見過$* 和 $1, $2 ... $9 等特殊變量,這些特殊變量包含了用戶從命令行輸入的參數(shù)。迄今為止,我們僅僅了解了一些簡單的命令行語法(比如一些強制性的參數(shù)和查看幫助的-h選項)。但是在編寫更復雜的程序時,您可能會發(fā)現(xiàn)您需要更多的自定義的選項。通常的慣例是在所有可選的參數(shù)之前加一個減號,后面再加上參數(shù)值 (比如文件名)。有好多方法可以實現(xiàn)對輸入?yún)?shù)的分析,但是下面的使用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 這個腳本是如何工作的呢?腳本首先在所有輸入命令行參數(shù)中進行循環(huán),將輸入?yún)?shù)與case表達式進行比較,如果匹配則設置一個變量并且移除該參數(shù)。根據(jù)unix系統(tǒng)的慣例,首先輸入的應該是包含減號的參數(shù).第2部分 實例 現(xiàn)在我們來討論編寫一個腳本的一般步驟。任何優(yōu)秀的腳本都應該具有幫助和輸入?yún)?shù)。并且寫一個偽腳本(framework.sh),該腳本包含了大多數(shù)腳本都需要的框架結構,是一個非常不錯的主意。這時候,在寫一個新的腳本時我們只需要執(zhí)行一下copy命令:cp framework.sh myscript 然后再插入自己的函數(shù)。 讓我們再看兩個例子: 二進制到十進制的轉換 腳本 b2d 將二進制數(shù) (比如 1101) 轉換為相應的十進制數(shù)。這也是一個用expr命令進行數(shù)學運算的例子:#!/bin/sh# vim: set sw=4 ts=4 et:help(){ cat <b2h -- convert binary to decimalUSAGE: b2h [-h] binarynumOPTIONS: -h help textEXAMPLE: b2h 111010will return 58HELP 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" ]; docase $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;;esacdone# The main programsum=0
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -