亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 5060 | 回復(fù): 13
打印 上一主題 下一主題

Unix系列shell程序編寫(下)  關(guān)閉 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2002-10-03 15:56 |只看該作者 |倒序瀏覽
Until語句

  While語句中,只要某條件為真,則重復(fù)執(zhí)行循環(huán)代碼,until語句正好同while相反,該語句使循環(huán)代碼重復(fù)執(zhí)行,直到遇到某一條件為真才停止。

Until語句的結(jié)構(gòu)如下:
until command
  do
    command
    command
    … …
  done

  可以用until語句替換上面?zhèn)浞莩绦虻膚hile語句,完成同樣的功能:

until [ $ANS != Y -a $ANS != y ]

for 循環(huán)
  在介紹for循環(huán)之前,我們要學(xué)個非常有用的unix命令:shift。我們知道,對于位置變量或命令行參數(shù),其個數(shù)必須是確定的,或者當(dāng)Shell程序不知道其個數(shù)時,可以把所有參數(shù)一起賦值給變量$*。若用戶要求Shell在不知道位置變量個數(shù)的情況下,還能逐個的把參數(shù)一一處理,也就是在$1后為$2,在$2后面為$3等。在 shift命令執(zhí)行前變量$1的值在shift命令執(zhí)行后就不可用了。

示例如下:

#測試shift命令(x_shift.sh)
    until [ $# -eq 0 ]
    do
         echo "第一個參數(shù)為: $1 參數(shù)個數(shù)為: $#"
         shift
    done
執(zhí)行以上程序x_shift.sh:
    $./x_shift.sh 1 2 3 4

結(jié)果顯示如下:

    第一個參數(shù)為: 1 參數(shù)個數(shù)為: 3
    第一個參數(shù)為: 2 參數(shù)個數(shù)為: 2
    第一個參數(shù)為: 3 參數(shù)個數(shù)為: 1
    第一個參數(shù)為: 4 參數(shù)個數(shù)為: 0

從上可知shift命令每執(zhí)行一次,變量的個數(shù)($#)減一,而變量值提前一位,下面代碼用until和shift命令計算所有命令行參數(shù)的和。

#shift上檔命令的應(yīng)用(x_shift2.sh)
    if [ $# -eq 0 ]
    then
        echo "Usage_shift2.sh 參數(shù)"
        exit 1
    fi
    sum=0
    until [ $# -eq 0 ]
    do
        sum=`expr $sum + $1`
        shift
    done
    echo "sum is: $sum"

執(zhí)行上述程序:

    $x_shift2.sh 10 20 15

其顯示結(jié)果為:

    45

  shift命令還有另外一個重要用途,Bsh定義了9個位置變量,從$1到$9,這并不意味著用戶在命令行只能使用9個參數(shù),借助shift命令可以訪問多于9個的參數(shù)。

  Shift命令一次移動參數(shù)的個數(shù)由其所帶的參數(shù)指定。例如當(dāng)shell程序處理完前九個命令行參數(shù)后,可以使用shift 9命令把$10移到$1。

  在熟悉了shift命令后,我們一起看看,Bsh程序中非常有用的for循環(huán)語句,這種循環(huán)同上面說的while和until循環(huán)不同,for語句中的循環(huán)是否執(zhí)行并不由某個條件的真和假來決定,決定for循環(huán)是否繼續(xù)的條件是參數(shù)表中是否還有未處理的參數(shù)。

For語句的結(jié)構(gòu)如下:

for variable in arg1 arg2 … argn
do
    command
    command
    … …
done

下面是for循環(huán)的簡單例子:

for LETTER in a b c d
do
     echo $LETTER
done

程序執(zhí)行結(jié)果如下:

a
b
c
d

在上面計算參數(shù)和的例子中,我們可以用for循環(huán),實現(xiàn)如下:

#測試 for 程序(x_for.sh)

if [ $# -eq 0 ]
then
   echo "Usage_for.sh 參數(shù)… …"
   exit 1
fi
sum=0
for I in $*
do
   sum=`expr $sum + $I`
done
echo "sum is: $sum"

中斷循環(huán)指令

  在程序循環(huán)語句中,我們有時候希望遇到某中情況時候結(jié)束本次循環(huán)執(zhí)行下次循環(huán)或結(jié)束這個循環(huán),這就涉及到兩條語句:continue和break。continue命令可使程序忽略其后循環(huán)體中的其他指令,直接進行下次循環(huán),而break命令則立刻結(jié)束循環(huán),執(zhí)行循環(huán)體后面的的語句。

#測試continue
I=1
while [ $I -lt 10 ]
do
  if [ $I -eq 3 ]
  then
    continue
  fi
  if [ $I -eq 7 ]
  then
    break
  fi
  echo "$I\c"
done

執(zhí)行上面程序,結(jié)果如下:

12456789
與或結(jié)構(gòu)

使用與/或結(jié)構(gòu)有條件的執(zhí)行命令

  Shell程序中可以使用多種不同的方法完成相同的功能,例如until和while語句就可以完成相同的功能,同樣,除了if-then-else結(jié)構(gòu)可以使命令有條件的執(zhí)行外,$$和||操作符也能完成上述功能。在C語言中這兩個操作符分別表示邏輯與和邏輯或操作。在Bourne Shell中,用&&連接兩條命令的含義只有前面一條命令成功執(zhí)行了,后面的命令才會執(zhí)行。

  &&操作的形式為:

    command && command

  例如語句:

    rm $TEMPDIR/* && echo "Files successfully removed"

  只有rm命令成功執(zhí)行以后,才會執(zhí)行echo命令。若用if-then語句實現(xiàn)上述功能,形式為:

    if rm $TEMPDIR/*
    then
      echo "Files successfully removed"
    fi
  相反,用||連接兩條命令的含義為只有第一條命令執(zhí)行失敗才執(zhí)行第二條命令,例如:

    rm $TEMPDIR/* || echo "File were not removed"

  上面語句的等價形式為:

    if rm $TEMPDIR/*
    then
      :
    else
      echo "Files were not removed"
    fi
  這兩種操作符可以聯(lián)合使用,如在下面的命令行中,只有command1和command2執(zhí)行成功后,command3才會執(zhí)行:

    command1 && command2 && command3

  下面的命令行表示只有command1成功執(zhí)行,command2不成功執(zhí)行時,才會執(zhí)行command3。

  &&和||操作符可以簡化命令條件執(zhí)行的格式,但一般只用于一條命令的條件執(zhí)行。如果許多命令都使用這兩個操作符,那么整個程序的可讀性將變的很差,所以在多條命令的條件執(zhí)行時,最好采用可讀性好的if語句。

函數(shù)

  現(xiàn)在我們介紹Shell程序中的函數(shù)部分,基本上任何高級語言都支持函數(shù)這個東西,能讓我們勝好多事情的東西,至少省的頻繁的敲擊相同的東西,好了come on
Shell程序中的函數(shù)

  函數(shù)又叫做子程序,可以在程序中的任何地方被調(diào)用,其格式如下:

  函數(shù)名字()
  {
    command
    ... ...
    command&#59;
  }

  Shell程序的任何地方都可以用命令 "函數(shù)名字" 調(diào)用,使用函數(shù)的好處有兩點,一點是使用函數(shù)可以把一個復(fù)雜的程序化為多個模塊,易于管理,符合結(jié)構(gòu)化程序的設(shè)計思想,另一個好處是代碼的重用。

  Shell函數(shù)和Shel程序比較相似,它們的區(qū)別在于Shell程序在子Shell中運行,而Shell函數(shù)在當(dāng)前Shell中運行。因此,在當(dāng)前Shell中可以看到Shell函數(shù)對變量的修改。在任何Shell中都可以定義函數(shù),包括交互式Shell。

  例如:

    $dir() {ls -l&#59;}

    結(jié)果是我們在$后面打dir,其顯示結(jié)果同ls -l的作用是相同的。該dir函數(shù)將一直保留到用戶從系統(tǒng)退出,或執(zhí)行了如下所示的unset命令:
    $unset dir
    下面的例子說明了函數(shù)還可以接受位置參數(shù):

    $dir(){_
    >echo "permission    ln owner   group    file sz last access
    >ls -l $*&#59;
    >}

    運行 dir a* 看產(chǎn)生什么結(jié)果

    參數(shù)a*傳遞到dir函數(shù)中并且代替了$*

    通常Shell程序?qū)⒃谧覵hell中執(zhí)行,該程序?qū)ψ兞康母淖冎辉谧覵hell中有效而在當(dāng)前Shell中無效。"."命令可以使Shell程序在當(dāng)前Shell中執(zhí)行。用戶可以在當(dāng)前Shell中定義函數(shù)和對變量賦值。通常用下面命令來重新初使化.profile對Shell環(huán)境的設(shè)置。
    $ . .profile
  由于看到這部分相對簡單,我們還是順便說說trap好了

使用trap命令進行例外處理

  用戶編寫程序在程序運行時可能會發(fā)生一些例外情況,比如執(zhí)行該程序的用戶按中斷鍵或使用kill命令,或者控制終端突然與系統(tǒng)斷開等。unix系統(tǒng)中的上述情況會使系統(tǒng)向進程發(fā)一個信號,通常情況下該信號使進程終止運行。有時侯用戶希望進程在接到終止信號時進行一些特殊的操作。若進程在運行時產(chǎn)生一些臨時文件,又因接受到的信號而終止。那么該進程產(chǎn)生的臨時文件將保留下來。在bsh中,用戶可以使用trap命令修改進程接收到終止信號時進行的默認操作。
  trap命令格式如下:

     trap command_string signals
多數(shù)系統(tǒng)中共有15種發(fā)給進程的信號,默認情況下大多數(shù)信號都會使程序終止。用戶最好查閱自己系統(tǒng)的文擋,看看本系統(tǒng)內(nèi)使用的信號種類。除了信號為9(真正的kill信號)不能使用trap命令外,其他信號所帶來的操作都可以用trap命令進行指定。下面是trap命令中經(jīng)常使用的幾種信號:

    信號   功能
    
     1     掛起
     2    操作中斷
     15    軟終止(kill信號)

  若命令串中包含不只一條命令,必須使用引號將整個命令括起來,具體是單引號還是雙引號,由用戶是否需要變量替換決定。" "替換,' '不替換。

  使用下面trap命令可以使程序在接收到掛起、中斷或kill信號時,首先把臨時文件刪除,然后退出:

    trap "rm $TEMPDIR/* $$&#59;exit" 1 2 15

  在上面例子中,當(dāng)Shell讀取trap命令時,首先對$TEMPDIR和$$進行變量替換,替換之后的命令串將被保存在trap表中,若上例中trap命令使用單引號時,trap命令執(zhí)行時候,不進行變量替換,而把命令串 rm $TEMPDIR/* $$&#59;exit 放到trap表中,當(dāng)檢測到信號時,程序解釋執(zhí)行trap表中的命令串,此時進行變量替換。前面變量$TEMPDIR和$$的值為執(zhí)行trap指令時候的值,后一種情況中變量的值為程序接收到信號時候的值,所以 "、'一定要區(qū)分仔細。

  下面命令的含義為用戶按二次中斷鍵后,程序才終止:

    trap 'trap 2' 2

  一般trap命令中的命令串中幾乎都包含exit語句,上面rm的例子若無exit語句,接收到信號rm命令執(zhí)行完后程序?qū)炱。但有時用戶也需要程序在接到信號后掛起,例如當(dāng)終端和系統(tǒng)斷開后,用戶發(fā)出掛起信號,并執(zhí)行空命令,如下:

    trap : 1

  若用戶想取消前trap指令設(shè)置的命令串,可以再執(zhí)行trap命令,在命令中不指定命令串表示接收到信號后進行默認的操作,命令如下:
    trap 1

規(guī)范Shell

獲取UNIX類型的選項:

  unix有一個優(yōu)點就是標準UNIX命令在執(zhí)行時都具有相同的命令行格式:

  command -options parameters

  如果在執(zhí)行Shell程序也采用上述格式,Bourne Shell中提供了一條獲取和處理命令行選項的語句,即getopts語句。該語句的格式為:

  getopts option_string variable

  其中option_string中包含一個有效的單字符選項。若getopts命令在命令行中發(fā)現(xiàn)了連字符,那么它將用連字符后面的字符同option_string相比較。若有匹配,則把變量variable的值設(shè)為該選項。若無匹配,則variable設(shè)為?。當(dāng)getopts發(fā)現(xiàn)連字符后面沒有字符,會返回一個非零的狀態(tài)值。Shell程序中可以利用getopts的返回值建立一個循環(huán)。

  下面代碼說明了date命令中怎么使用getopts命令處理各種選項,該程序除了完成unix的標準命令date的功能外,還增加了許多新的選項。
  #新date程序
  if [ $# -lt 1 ]
  then
    date
  else
    while getopts mdyDHMSTJjwahr OPTION
    do
      case $OPTION
      in
        m)date '+%m'&#59;&#59;
        d)date '+%d'&#59;&#59;
        y)date '+%y'&#59;&#59;
        D)date '+%D'&#59;&#59;
        H0date '+%H'&#59;&#59;
        M)date '+%M'&#59;&#59;
        S)date '+%S'&#59;&#59;
        T)date '+%T'&#59;&#59;
        j)date '+%j'&#59;&#59;
        J)date '+%y%j'&#59;&#59;
        w)date '+%w'&#59;&#59;
        a)date '+%a'&#59;&#59;
        h)date '+%h'&#59;&#59;
        r)date '+%r'&#59;&#59;
        \?)echo "無效的選項!$OPTION"&#59;&#59;
      esac
    done
  fi

  有時侯選項中還帶一個值,getopts命令同樣也支持這一功能。這時需要在option_string中選項字母后加一個冒號。當(dāng)getopts命令發(fā)現(xiàn)冒號后,會從命令行該選項后讀取該值。若該值存在,那么將被存在一個特殊的變量OPTARG中。如果該值不存在,getopts命令將在OPTARG中存放一個問號,并且在標準錯誤輸出上顯示一條消息。

  下面的例子,實現(xiàn)拷貝一個文件,并給文件賦一個新的名字。-c選項指定程序拷貝的次數(shù),-v選項要求顯示新創(chuàng)建文件的文件名。

  #--拷貝程序

  COPIES=1
  VERBOSE=N
  while getopts vc:OPTION
  do
    case $OPTION
    in
      c)COPIES=$OPTARG&#59;&#59;
      v)VERBOSE=Y&#59;&#59;
      \?)echo "無效參數(shù)!"
        exit 1&#59;&#59;
    esac
  done
  if [ $OPTIND -gt $# ]
  then
    echo "No file name specified"
     exit 2
  fi
  shift 'expr $OPTIND - 1'
  FILE=$1
  COPY=0
  while [ $COPIES -gt $COPY ]
  do
    COPY='expr $COPY + 1'
    cp $FILE $ {FILE} $ {COPY}
    if [ VERBOSE = Y }
    then
      echo ${FILE} $ {COPY}
    fi
  done


規(guī)范Shell:

  我們知道環(huán)境變量PS1是提示符,看下面程序chdir:
  if [ ! -d "$!" ]
  then
    echo "$1 is not a directory"
    exit 1
  fi
  cd $1
  PS1="'pwd'>"
  export PS1

  我們執(zhí)行:

    $chdir /usr/ice666

  結(jié)果提示符號變成/usr/ice666>了嗎?沒有,為什么?

  原因在于:chdir在子Shell中執(zhí)行,變量PS1的修改在當(dāng)前Shell中也不會起作用,若要chdir完成意想中的功能,必須在當(dāng)前Shell中執(zhí)行該命令。最好的方法就是把其改成一個函數(shù)并且在.profile文件中定義。但若要把函數(shù)放到單個文件中并在當(dāng)前Shell中執(zhí)行,則需要使用 . 命令,并將chdir重寫成一個函數(shù),把其中的exit改寫成return。下面代碼是 .ice_ps的內(nèi)容:

  #--提示符
  chdir()
  {
  if [ !-d "$1" ]
  then
    echo " $1 is not a directory"
    return
  fi
  cd $1
  PS1="'pwd'>"
  export PS1&#59;
  }

  然后我們在.profile文件中加入下面語句

  .ice_ps

  然后在切換目錄的時候,我們用chdir命令,結(jié)果是什么呢,自己實驗好了!  
調(diào)試Shell程序
1>調(diào)試shell程序

  用戶剛編寫完Shell程序中,不可避免的會有錯誤,這時我們可以利用Bsh中提供的跟蹤選項,該選項會顯示剛剛執(zhí)行的命令及參數(shù)。用戶可以通過set命令打開-x選項或在啟動Shell使用-x選項將Shell設(shè)置成跟蹤模式。例如有下面代碼ice_tx:

  if [ $# -eq 0 ]
  then
    echo "usage:sumints integer list"
    exit 1
  fi
  sum=0
  until [ $# -eq 0 ]
  do
    sum='expr $sum + $1'
    shift
  done
  echo $sum

  我們用跟蹤模式運行:

  $sh -x ice_tx 2 3 4
  結(jié)果顯示:
  +[ 3 -eq 0 ]
  +sum=0
  +[ 3 -eq 0 ]
  +expr 0+2
  +sum=2
  +shift
  +[ 2 -eq 0 ]
  +expr 2+3
  +sum=5
  +shift
  +[ 1 -eq 0 ]
  +expr 5+4
  +sum=9
  +[ 0 -eq 0 ]
  +echo 9
  9

  從上面可以看出,跟蹤模式下Shell顯示執(zhí)行的每一條命令以及該命令使用的變量替換后的參數(shù)值。一些控制字如if、then、until等沒顯示。
2>命令分組

  Shell中若干命令可以組成一個單元一起執(zhí)行。為了標識一組命令,這些命令必須放到"()"或"{}"中。放在"()"中的命令將在子Shell中運行,而放在"{}"中的命令將在當(dāng)前Shell中運行。子Shell中運行的命令不影響當(dāng)前Shell的變量。當(dāng)前Shell中運行的命令影響當(dāng)前Shell的變量。

  $NUMBER=2
  $(A=2&#59;B=2&#59;NUMBER='expr $A+$B'&#59;echo $NUMBER)
  結(jié)果為:4
  $echo $NUMBER
  結(jié)果為:2
  如果把上面的()變成{},結(jié)果會是怎么樣的呢?

3>使用Shell分層管理器shl

  UNIX是一個多道程序設(shè)計的操作系統(tǒng),一些UNIX系統(tǒng)利用這一特性提供了Shell層次管理器shl。使用shl用戶一次可以打開多個層次的Shell,其中活躍的Shell可以從終端上獲得輸入。但所有Shell的輸出都可在終端上顯示,除非顯示被禁止。

  多個Shell中有一個為shl,當(dāng)用戶在某個Shell中工作時,可以通過使用特殊字符(一般為Ctrl+z)返回shl。為了同其他Shell區(qū)別,shl中提示符為">>>"。當(dāng)用戶工作在Shell層次管理器中時,可以創(chuàng)建、激活和刪除Shell,下面是shl中使用的命令。

  create name    產(chǎn)生名為name的層次
  delete name    刪除名為name的層次
  block name     禁止名為name的層次的輸出
  unblock name    恢復(fù)名為name的層次的輸出
  resume name    激活名為name的層次
  toggle       激活近來經(jīng)常使用的層次
  name        激活名為name的層次

  layers [-l] name  對于表中的每個層次,顯示其正在運行的進程的進程號,-l選項要求顯示詳細信息。

  help        顯示shl命令的幫助信息
  quit        退出shl以及所有被激活的層次

總結(jié)

  在前面我們主要介紹了sh的變量、基本語法、程序設(shè)計等。如果掌握了這些內(nèi)容,在學(xué)習(xí)其他UNIX下編程語言的時候,相信有一定的好處,我們說了,在大多數(shù)的UNIX中都提供Bourn Shell,而且很少有象sh這樣強大的腳本編輯語言了,是系統(tǒng)管理員和程序員的一筆財富,并且不需要額外的軟件環(huán)境,對文件等處理借助unix命令,實現(xiàn)起來比c實現(xiàn)還要簡單。






論壇徽章:
0
2 [報告]
發(fā)表于 2002-10-03 16:03 |只看該作者

Unix系列shell程序編寫(下)

放到精華里做為新手必讀吧.

論壇徽章:
0
3 [報告]
發(fā)表于 2002-10-03 16:12 |只看該作者

Unix系列shell程序編寫(下)

版主: 上篇、中篇都蓋了章,這一篇給忘了耶

論壇徽章:
0
4 [報告]
發(fā)表于 2002-10-03 16:13 |只看該作者

Unix系列shell程序編寫(下)

o,已蓋上了

論壇徽章:
0
5 [報告]
發(fā)表于 2002-10-03 16:15 |只看該作者

Unix系列shell程序編寫(下)

gql88 兄雖是“新手”,貢獻不小

論壇徽章:
0
6 [報告]
發(fā)表于 2002-10-03 16:16 |只看該作者

Unix系列shell程序編寫(下)

又搞錯了,已是俠客了

論壇徽章:
0
7 [報告]
發(fā)表于 2002-10-03 16:39 |只看該作者

Unix系列shell程序編寫(下)

俺不喜歡看到?jīng)]有回復(fù)的帖子.
便三句話貼三處,一一蓋章了.hihi.

山地獾      ,加班呢?

論壇徽章:
0
8 [報告]
發(fā)表于 2002-10-03 20:39 |只看該作者

Unix系列shell程序編寫(下)

加著班,抽空又上來轉(zhuǎn)轉(zhuǎn)。版主不是說要去海邊劃船嗎?怎么天天都見你有上來,莫非是無線上網(wǎng)?

論壇徽章:
0
9 [報告]
發(fā)表于 2002-10-04 18:02 |只看該作者

Unix系列shell程序編寫(下)

劃船?中國的亞運健兒劃船可厲害了。
斑竹是不是很厲害呀?說不準是中國2004年奧運會的“秘密武器”。

論壇徽章:
0
10 [報告]
發(fā)表于 2002-10-05 20:39 |只看該作者

Unix系列shell程序編寫(下)

[這個貼子最后由valentine在 2002/10/05 08:42pm 編輯]

俺4號和幾個朋友去海上釣了一天魚.沒有上網(wǎng)啊!
甭題劃船了,機動船.
最后把哥幾個吧漁民一早上的收獲全帶回家才沒餓著老婆孩子.
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP