2011年9月22日 星期四

資訊隱藏的障礙

1. 資訊過份分散:
  • 如直接將100這個數字當成程式碼,將100當成常值,將導致對它的參數過度分散,最好將此部份的資訊隱藏起來,例如:寫入稱為MAX_EMPLOYESS的常數中,僅對於一處對其直進行變更。  
  • 最好將與使用者的互動集中在單獨的類別、封裝或系統中。
  •  
2. 循環相依性:

  • ex. A類別的常式呼叫了B類別的常式,B類別的常式又呼叫了A類別的常式。應該避免形成這種依賴的迴圈
3. 將類別資料誤認為全域資料
  • 全域資料通常受到兩種問題影響:
  1. 常式在全域資料上操作,但卻不知道還有其他常式也正用這些全域資料操作。
  2. 常式知道其他常式正用全域資料進行操作,但卻無法清楚知道它們所進行的操作。
  • 類別資料就不會遇到這些問題,因為只有類別內的少數常數才能直接存取這些資料。

4. 可察覺的效能減損

2011年9月21日 星期三

軟體分層設計的益處

1. 可區分文亂的劣等程式碼 。
2. 若最終能捨棄就程式碼或進行重整,除介面層外,將不必修改新程式碼。

2011年9月20日 星期二

上游的前置作業:依照程式前置作業所需完備度 選擇使用重複法或循序法

1. 選擇使用循序性的方法
  • 需求相當穩定時。
  • 設計是平鋪直敘,且相當容易瞭解。
  • 開發團隊十分熟悉該應用領域。
  • 專案所含風險極少。
  • 長期的可預測性十分重要。
  • 在下遊階段變更需求、設計及程式碼的成本可能會很高。

2. 選擇使用重複性的方法
  • 需求不易瞭解,或因為其他原因,您預期它們會不穩定。
  • 設計很複雜、很艱難,或兩者皆有。
  • 開發團隊十分不熟悉該應用領域。
  • 專案含有大量風險
  • 長期的可預測性不重要。
  • 在下遊階段變更需求、設計及程式碼的成本可能不會很高。 
由於軟體本身的性質使然,重複法通常會比循序法更有用。

    2011年9月9日 星期五

    c 分析命令列參數

    標頭檔: unistd.h

    原型:
    int getopt(int argc, char * const argv[], const char *optstring);
    說明:
    用來分析命令列參數,引數argc和argv是由 main()傳遞的參數個數和內容。
    參數 optstring 是有效選項(字母)。如 " a:bf"。代表要接受的option有 -a, -b, -f。
    其中option a的後面是":"號,代表-a option後還有參數(例如-aext2)。
              getopt提供三個global variable :
              optarg: 像a:這樣的參數,getopt會將-a後面的字串放到optarg中。
              optopt: 有額外參數時,optopt 會儲存option,如果getopt()找不到符合的參數則會
                           列印錯誤,並將全域變數optopt設為'?'字元。
              opterr: 如果不希望getopt()印出錯誤訊息則只要將全域變數opterr設為0即可。

    傳回值:
             參數字母: 如果找到符合的參數
             '?':  如果參數不包含在引數optstring 的選項字母
             -1:  分析結束

    範例:
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[])
    {
      int ch;
      opterr = 0; //不印出錯誤訊息
    while((ch=getopt(argc,argv,"a:cef"))!=-1)
      switch(ch)
     {
      case 'a':
         printf("choose a: %s\n",optarg);
         break;
      case 'c':
         printf("option c\n");
         break;
      case 'f':
        printf("option f\n");
        break;
      default:
        printf("other option: %c\n",ch);
        break;
    
     }
    printf("optopt = %c\n",optopt);
    }
    
    
    結果:
    [root@localhost shelltest]# ./test -acef   
    choose a: cef
    optopt = 
    [root@localhost shelltest]# ./test -a   
    other option: ?
    optopt = a 
    [root@localhost shelltest]# ./test -aaa
    choose a: aa
    optopt =
    [root@localhost shelltest]# ./test -c
    option c
    optopt =
    [root@localhost shelltest]# ./test -cc
    option c
    option c
    optopt =
    source code http://opencobol.add1tocobol.com/doxy/dc/d53/getopt_8c.html

    2011年9月7日 星期三

    shell script po文測試標題

    一 基本觀念
    1. 回應目前所使用的shell為何?
      $echo $SHELL
    2. 通配符號
      ? 任何一個字符
      * 任何字符(一串字符)
      [set] 在set中的任何字符
      [!set] 不在set中的任何字符
    3. 大括弧擴展
      {,{,},}
      ex. echo b{ed,olt,ar}s   結果列印 beds bolts bars
      ex. echo b{ar{d,n,k},ed}s 結果列印bards barns barks beds
      ex. echo {d..h} 結果看到 d e f g h  
      至少要有一個逗號 否則所產生的單字會維持原狀 ex. b{o}lt 還是被當成b{o}lt
     
    4. 背景執行
      指令後面加&
     
    5. 檢視背景執行
      $jobs
     
    6. nice command
      $nice command
      command 以比較低的優先權處理
    7. 特殊字符與加引號
      ~ 主目錄
      ` 命令替換(舊式)
      # 註解
      $ 變數表示示
      & 背景工作
      * 字串通配符
      ( 啟動subshell
      ) 終止subshell
      \ 引述下一個字符
      | 導管
      [ 起始字符集通配符
      ] 終止字符集通配符
      { 起始命令區塊
      } 終止命令區塊
      ; shell命令之區隔符
      ' 強引號
      " 弱引號
      < 輸入轉向
      > 輸出轉向
      / 路徑名稱之目錄區隔符
      ? 單字符通配符
      ! 管線之邏輯NOT算符
     
    8. 去除特殊字符的字面意義
      a.)加單引號(quoting)---
      去除特殊字符的字面意義
      ex. $echo '2 * 3 > 5 is a valid inequality.'

      b.)以倒斜線規避
      ex. $echo 2 \* 3 \> 5 is a valid inequality.

    9. 控制鍵
      控制鍵    相應的stty名稱    功能
      ^C        intr              結束現行命令
      ^D        eof               結束輸入
      ^\        quit              結束現行命令,如果CTRL-C管用的話
      ^S        stop              停止輸出到螢幕上
      ^Q                          開始輸出到螢幕上
      ^?或DEL   erase             刪除最後一個字符
      ^U        kill              刪除整個命令列
      ^Z/^Y     susp              暫停現行的命令
      ^W                          werase
      ^R                          rprnt
      ^O                          flush
      ^V                          lnext
      可以使用stty -a 查看設定


    二 編輯命令列
    emacs 編輯模式
    1. 基本指令
    ^B  將游標往後(backward)移一個字符(不會進行刪除動作)
    ^F  將游標往前(forward)移一個字符
    DEL 往後(backward)刪除一個字符
    ^D  往前(forward)刪除一個字符

    2. 單字處理命令
    ESC-B   將游標往後(backward)移動一個單字
    ESC-F   將游標往前(forward)移動一個單字  
    ESC-DEL 往後刪除(kill)一個單字
    ESC-^-H 往後刪除一個單字
    ESC-D   往前刪除一個單字
    ^-Y     取回(yank)上一次所刪除的項目

    3. 列處理命令
    ^-A   移到列的開頭
    ^-E   移到列的結尾
    ^-K   往前刪除一整列

    4. 在歷程檔中遊走
    ^-P     移到上一頁
    ^-N     移到下一頁
    ^-R     往回搜尋
    ESC-<   移到歷程的第一列
    ESC->   移到歷程的最後一列

    5. 文字補全
    tab     試圖進行一般的補全功能
    ESC-?   列出可能的補全結果

    ESC-/   試圖補全檔案名稱
    ^-X/    列出可能的『檔案名稱』補全結果
    ESC-~   試圖補全用戶名稱
    ^-X~    列出可能的『用戶名稱』補全結果
    ESC-$   試圖補全變數
    ^-X$    列出可能的變數補全結果
    ESC-@   試圖補全主機名稱
    ^-X@    列出可能的『主機名稱』補全結果
    ESC-!   試圖補全命令
    ^-X!    列出可能的『命令』補全結果
    ESC-TAB 試圖以歷程紀錄(history list)中之前所鍵入的命令進行補全

    6. 雜項命令
    ^-J     同RETURN
    ^-L     清除螢幕,將現行(current)列置於螢幕頂端
    ^-M     同RETURN
    ^-O     同RETURN,但會接著顯示命令歷程中的下一列
    ^-T     將標點兩邊的字符對調,並將標點向右移動一個位置
    ^-U     刪除從列的開頭到標點為止的部份
    ^-V     未下一個字符加上引號(規避該字符的特殊意義,如果有特殊意義的話)
    ^-[     同ESC(適用於大多數鍵盤)
    ^-C     將標點右邊的單字(word)換成大寫字母開頭
    ^-U     將標點右邊的單字全部換成大寫字母
    ^-L     將標點右邊的單字全部換成小寫字母
    ESC-.   在標點右邊插入上一道命令列的最後一個單字
    ESC-_   同ESC-.


    vi 編輯模式

    0. vi輸入模式的編輯命令
    del   刪除前一個字
    ^-w   刪除前一個單字
    ^-v   為下一個字符加上引號
    esc   進入控制模式

    以下所有命令都可以前置一個數字(n)做為重複次數
    1. 簡單的控制模式命令
    h   往左移一個字 (與編輯時^+H有關)
    l   往右移一個字
    w   往右移一個單字
    b   往左移一個單字
    W   移到下一個非空白單字的開頭
    B   移到前一個非空白單字的開頭
    e   移到現行單字的末端
    E   移到現行非空白單字的末端
    0(zero) 移到一列之首
    ^   移到一列之第一個非空白字符
    $   移到一列的的末端

    2.  鍵入和更改文字

    i    字前插入文字(插入)
    a    字後插入文字(添加)
    I = 0i    列首插入文字
    A = $a    列尾插入文字
    R       覆蓋既有文字(Replace in edit mode)
    (n)r    覆蓋既有文字(command)

    3. 刪除命令
    用c替代d,會在做完刪除後進入輸入模式
    dh    往左刪除一個字
    dl    往右刪除一個字
    db    往左刪除一個單字
    dw    往右刪除一個單字
    dB    往左刪除一個非空白單字
    dW    往右刪除一個非空白單字
    d$    一直刪除到行尾端
    d0    一直刪除到行開端

    D = d$
    dd = 0d$
    C = c$
    cc = 0c$
    X = dh
    x = dl

    u    undo(undelete)
    .    重複上次文字修改命令
    y(yank)    擷取
    p    文字插入在字的右邊
    P    文字插入在字的左邊

    4. 在歷史檔中遊走

    k = -    往後移動一列
    j = +    往前移動一列 (與編輯時^+J有關)
    G = gg    移動到重複次數所指定的命令列
    /string    往後搜尋字串string
    ?string    往前搜尋字串string
    n    依上次搜尋方向重複搜尋
    N    依上次搜尋反方向重複搜尋

    5. 尋找字符命令
    fn    向右移動到下一個n所在位置
    Fn    向左移動到前一個n所在位置
    tn    fn+移回一格
    Tn    Fn+往前移一格
    |

    三. 訂製你的環境
    1. 啟動檔: .bash_profile .bash_logout .bashrc
        登入系統檔案尋找順序(找不到檔案便會往下一個檔案找): .bash_profile -> .bash_login -> .profile
        離開login shell :會執行.bash_logout
        .bash_profile只會被login shell    所讀取與執行。如果在命令列上以鍵入bash的方式啟動一個新的shell(一個shushell),它會試圖從.bashrc檔中讀取命令。
    2. 別名:
        alias name='command' or command    //=兩邊不能有空格
        可以替別名取另一個別名,也就是別名可以遞迴定義。
       
        alias listfile=ls
        alias ls=listfile  //那麼別名listfile將會被略過不計。
       
        bash隱晦功能:如果一個別名的值(等號的右邊部分)是以一個空格結束的,那麼bash便會對命令列的下一個單字進行別名替換。要讓別名的值以空格結束,得要為它加上引號。

        alias name 或 alias : 會列出別名設定。
    3. 選項:
        set -o optionname (開啟option) 和 set +o optionname(關閉option)
        3.1 shopt
            -p 列出可設定的shell選項以及他們目前的設定值。
            -s 設定(set)或開啟每個選項名稱。
            -u 取消(unset)或關閉每個選項名稱。
            -q 抑制正常輸出;傳回狀態會指出一個變數是否有被設定。
            -o 允許選項名稱的值成為set命令以-o選項所定義的值。

    4. shell變數:
        varname='value' or value //=兩邊不能有空格
        變數使用$varname
        查看變數值 可使用echo $varname
        4.1 變數以及加引號
            雙引號裡的特殊字符會被shell解釋
            單引號裡的特殊字符完全不會遭到shell的解釋
        4.2 內建變數
            4.2.1 編輯模式變數

            4.2.2 郵件變數
                MAIL    郵件檔的名稱,用以檢查有無新收到的郵件
                  郵件檔 /usr/mail/yourname
                  只要設定 MAIL=/usr/mail/yourname 就行了。

                MAILCHECK    多久檢查一次新郵件,以秒為單位(預設60秒)
                MAILPATH    郵件檔名單,以冒號(:)為分隔符,用來檢查新收到的郵件。
                  ex.     MAILPATH=/usr/mail/you/martin:/usr/mail/you/geoffm:/usr/mail/you/paulr
                          MAILPARH="\
                          /usr/mail/you/martin?you have mail from Martin.:\
                          /usr/mail/you/geoffm?Mail from Geoff has arrived.:\
                          /usr/mail/you/paulr?There is new mail from Paul."
                $_ 顯示幕前的郵件檔名稱

            4.2.3 提示變數
                分別存放在PS1 PS2 PS3 PS4
                提示字串的制定命令
                \a    ASCII的響鈴(bell)字符(007)
                \A    採用24小時制,以HH:MM的格式來顯示現在的時間
                \d    以Weekday Month Day的格式來顯示日期
                \D{format}    format會被傳入strftime(3),所產生的結果會被插入提示字串;如果format為空值,則會以語系特定的格式來顯示時間
                \e    ESC(033)
                \H    主機名稱
                \h    主機名稱中第一個.之前的部分
                \j    shell目前所控管的工作數量
                \l    shell之終機端名稱的基本名稱(basename)
                \n    LR+LF
                \r    LR
                \s    shell的名稱
                \T    採用12小時制,以HH:MM:SS的格式來顯示現在的時間
                \t    以HH:MM:SS的格式來顯示現在的時間
                \@    採用12小時制,以am/pm的格式來顯示現在的時間
                \u    現行使用者的用戶名稱
                \v    bash的版本 ex.2.00
                \V    bash的發行版本;版本和修補次數 ex.2.00.0
                \w    現行工作目錄
                \W    現行工作目錄的基本名稱(basename)
                \#    現行命令的命令編號
                \!    現行命令的歷程編號
                \$    如果有效的UID是0,就顯示一個"#"符號,否則就顯示一個"$"符號
                \nnn    八進制的字符碼
                \\    顯示一個到斜線
                \[    非列印(non-printing)字符序列的開頭,像是終端機的控制序列
                \]    非列印(non-printing)字符序列的結尾。

            4.2.4 命令的搜尋路徑
                在.bash_profile加入PATH: PATH=$PATH:"/home/you/bin"

            4.2.5 將命令的路徑存入雜湊表
                hash 查看雜湊表內容
                hash -r    移除hash的一切
                hash -d    name    移除特定的命令名稱
                hash -p namepath    加入特定的命令路徑
               
                使用set 指定hashall 選項開關hash

            4.2.6 目錄的搜尋路徑和變數
                CDPATH 值如同PATH
                    空字串代表現行目錄

            4.2.7 雜項變數
                HOME    你的主機(登入)目錄名稱
                SECONDS    shell被調用之後所持續的秒數
                BASH    你所執行之shell的路徑名稱
                BASH_VERSION    你所執行之shell的版本編號
                BASH_VERSINFO    你所執行之shell的版本資訊陣列
                PWD    現行目錄
                OLDPWD    執行上一次cd命令之前所在的目錄
        5. 定製與子行程
            5.1 環境變數
                export varnames
                export or export -p 察看環境變數

                TERM=trythisone emacs filename

    四. shell 程式設計基礎

        1. shell 命令稿與函式
            執行script方法:
                        1. source scriptname
                        2. 鍵入檔案名稱+enter
            ./scriptname :相當於鍵入命令稿的絕對路徑
            透過名稱調用命令稿之前需要先賦予它執行權

            差異:
                source scriptname    shell:        ---->--script-->---->    在同一個shell上執行script

                scriptname            shell:        ---->           ---->    shell等待subshell執行完script後繼續執行
                                    subshell:         --script-->        在subshell上執行script

                scriptname&            shell:        ---->...........---->    subshell執行同時shell繼續執行(subshell在背景執行)
                                    subshell         --script-->        在背景subshell執行script

            1.1 函式
                表示方式:
                1.
                function functname
                {
                  shell commands
                }
                或
                2.
                functname ()
                {
                  shell commands
                }

                可以使用unset -f functname 刪除某個函式的定義
                declare -f :查看登入時間定義了那些函式
                declare -F :僅查看函式的名稱

                函式與script差異:    1. 函式並不會以名子來調用script那樣被執行在另一個行程中,執行一個函式的語意比較像是登入系統時,.bash_profile檔所做的事或是像以source命令來調用任何script。
                                    2. 函式與script同名時,函式具有優先執行的權利

                各種命令優先權:
                                    1. 別名
                                    2. function 以及 if 和for 之類的關鍵字
                                    3. 函式
                                    4. 內建命令,像是cd 和type
                                    5. script和可執行的程式,shell會根據PATH環境變數裡所列舉的目錄來搜尋他們
                如果名稱相同,別名會比函式和script具有更高的執行優先權。可以使用command,builtin 和 enable等內建命令來改變他們優先執行順序。
               
                type name : 解釋bash命令方式
                            type -a name 查看name所有定義
                            type -p name 查看限制為可執行檔或shell script
                            type -P name 查看限制為可執行檔或shell script 即使-t選項回傳值不是file
                            type -f name 查看只支援關鍵字、檔案以及別名。
                            type -t name 只查看描述單字alas, keyword, function, builtin 或file
                            -t可以和其他選項一起使用

        2. shell變數
            可以使用$VAR 取得值
            可以透過export讓子行程知道
            2.1 位置參數
                唯讀不能指定新值
                1 2 3等等: 他們的值$1 $2 $3表示第一個到第三個輸入參數

                0 值$0 : 代表script file name

                * 和 @ : 這2個特殊變數包含了所有的位置參數(位置參數0除外),兩者之間的差異相當微妙但很重要,而且只有當他們被雙引號刮住時,才會凸顯此一差異。
                    "$*" : 是一個包含所有位置參數的單一字串,並以環境變數IFS(internal field separator)中的第一個字符做為位置參數的分隔符;IFS的預設通常是一個空格、跳格或換行符號。
                    "$@" : 相當於"$1" "$2" ..."$N" N代表參數數目相當於N個以雙引號刮住的字串,並以空格為分隔符

                #    : 存放位置參數的數目
                2.1.1 函式中的位置參數
                -----------------------------------
                |         ascript(script)            |
                |    -------------                    |
                |    |    $var1    |                    |   
                |    -------------                    |
                |    -------------                    |
                |    |    $0        |                    |
                |    -------------                    |
                |    -------------                    |
                |    |    $1        |                    |
                |    -------------                    |
                |    -------------                    |
                |    |    $2        |                    |
                |    -------------                    |
                |    ---------------------            |
                |    |  函式 afunc        |            |
                |    |    -------------    |            |
                |    |    |    $1        |    |            |
                |    |    -------------    |            |
                |    |    -------------    |            |
                |    |    |    $2        |    |            |
                |    |    -------------    |            |
                |    ---------------------            |
                -----------------------------------
                $var1 $0 在ascript(script)和函式afunc都看的到
                script的$1 $2 只有在script看的到
                函式的$1 $2 只有在函式看的到

            2.2 函式裡的區域變數
                local var    #設定為區域變數

            2.3 具引號的$@和$*
                為什麼"$*"中的元素要以IFS的第一個字符做為分隔符號,而不使用空格就好?這是為了讓你的輸出具有彈性。
                為什麼"$@"的行為就好像是N個被加上雙引號的字串?這是為了讓你能再以分開的值來使用他們。
            2.4 變數的另一種語法
                除了$varname 外,還有${varname} 這個更一般化之語法的簡單形式。
                為什麼會有兩種語法?
                    1. 如果你的程式碼參用到九個以上的位置參數時你必須用${10}來表示第十個參數,不可以用$10
                    2. 如果想要在變數後面加一個底線之類符號
        3. 字串算符
            字串算符能讓你作以下幾件特別的事:
                確定變數存在與否(亦既有被定義而且其值不是空的)
                為變數設定預設值
                捕捉因變數未被設定所導致的錯誤
                移除變數值中與樣式相符的部份
            3.1 字串算符的語法
                字串算符的語法,基本上就是將具運算能力的特殊字符擺在變數名稱與右括號之間,而算符所需要的任何引數則會擺在算符的右邊。
                ${varname:-word} :    若varname存在而且不是空的,則傳為它的值;否則傳回word。
                                    目的:若此變數沒有被定義,則傳回一個預設值。
                                    ex.:  若count沒有定義 ${count:-0}的求值結果為0

                ${varname:=word} :    若varname存在而且不是空的,則傳回他的值;否則就把他設成word,然後傳回它的值。位置參數和特殊參數不能以這種方式指定。
                                    目的:若某個變數沒有被定義,則為他設定一個預設值。
                                    ex.: 若count沒有定義 ${count:=0} 會把count設成0。

                ${varname:?message} :    若varname存在而且不是空,則傳回它的值;否則印出varname:message,並放棄現行的命令或命令稿 (只適用於以非互動方式操作的shell)。若省略message則會產生parameter null or net set
                                    目的:捕捉因變數未定義所導致的錯誤。
                                    ex.: 若count沒有定義 ${count:?"undedined!"}會顯示 count:undefined!

                ${varname:+word}    若varname存在而且不是空的,則傳回word;否則傳回空值(null)。
                                    目的:測試某個變數存在與否。
                                    ex.: 若count有定義 ${count:+1}會傳回1(代表此事為真)。

                ${varname:offset:length} :進行子字串的擴展(substring expansion)。它會傳回$varname中開始位置為offset,字符個數為length的子字串。
                                        $varname中第一個字符的位置編號為0。若省略length,這個子字串將會從offset開始,一直延續到$varname的末端。
                                        如果offset小於0,那麼位置會從$varname的末端開始算起。
                                        如果varname是@,哪麼length就是從參數offset開始算起之位置參數的數目。
                                        目的:傳回某個字串的一部分(子子串或切片)
                                        ex.若count被設成frogfootman,則${count:4}會傳回footman。而${count:4:4}會傳回foot。

            3.2 樣式以及樣式比對
                ${variable#pattern}        如果pattern與變數值的開頭相符就刪除相符的部分(取最短者),並傳回變數其餘的部份。
                ${variable##pattern}    如果pattern與變數值的開頭相符就刪除相符的部分(取最長者),並傳回變數其餘的部份。
                ${variable%pattern}        如果pattern與變數值的結尾相符就刪除相符的部分(取最短者),並傳回變數其餘的部份。
                ${variable%%pattern}    如果pattern與變數值的結尾相符就刪除相符的部分(取最長者),並傳回變數其餘的部份。

                ${varable/pattern/string}
                ${varable//pattern/string}    在variable中符合pattern的部份(取最常者)會被取代成string。
                                            如果是第一種形式,只有的一個相符的部份會被取代。
                                            如果是第二種形式,所有相符的部份都會被取代。
                                            如果pattern是以一個#開始的,它就必須比對變數的開頭。
                                            如果pattern是以一個%開始的,它就必須和變數的結尾進行比對。
                                            如果string是空的,符合的部份會被刪除。
                                            如果variable是@或*,則會依序對每個位置參數作此操作。
            3.3 長度算符
                ${#varname}        它會傳回字符串之變數值的長度。

            3.4 經延伸的pattern比對算符
                *(patternlist)     所指定的pattern出現零或多次,代表符。
                +(patternlist)     所指定的pattern出現一或多次,代表符。
                ?(patternlist)     所指定的pattern出現零或一次,代表符。
                @(patternlist)     所指定的pattern出現一次,代表符。
                !(patternlist)     相符於任何pattern,但所指定的樣式除外。
        4. 命令替換
            $(UNIX Command)
       
    五. 流程控制
        1. if/else
            if condition
            then
                statements
            [elif condition
                ethen statements...]
            [else
                statements]
            fi

            1.1 結束狀態
                0 通常代表沒問題的結束狀態。 其他編號(1~255)通常代表錯誤。
                如果結束狀態=0, condition 會被判定為真; 若為其他值則判定為否。

                $?    最後一個執行之命令的狀態。
            1.2 return N
                return 只能用在函式和以source 執行的shell script。相對而言exit N 會結束整個shell script。
               
            1.3 合併結束命令
                statement1 && statement2 執行statement1,如果它的結束狀態是0(true),繼續執行statement2。
                statement1 || statement2 執行statement1,如果它的結束狀態不是0(true),繼續執行statement2。

            1.4 條件測試
                [...]
                [[...]] 如同[...]但不會對括符裡的單字進行單字分離和路徑名稱擴展的動作。
               
                1.4.1 字串比較
                    字串比較算符
                    算符        若...為真
                    ==================================================================               
                    str1=str2    str1與str2相符
                    str1!=str2    str1與str2不相符
                    str1<str2    str1小於str2
                    str1>str2    str2大於str2
                    -n str1        str1不是空的
                    -z str1        str1是空的
               
                1.4.2 檔案屬性檢查
                    檔案屬性算符
                    算符        若...為真
                    ==================================================================               
                    -a file        file 存在
                    -d file        file 存在,而且是一個目錄。
                    -e file        file 存在;如同-a
                    -f file        file 存在,而且是一個普通檔案(並非目錄或其他特殊檔)
                    -r file        擁有file的讀取權
                    -x file        擁有file的執行權,或目錄的搜尋權
                    -N file        自從上次讀取後file已被修改過
                    -O file        擁有file的所有權
                    -G file        file的群組識別碼符合你的群組識別碼,或是你的群組識別碼中的一個(如果你同時隸屬於多個群組)
                    file1 -nt file2    file1比file2還新
                    file1 -ot file2    file1比file2還舊

                    if [ condition ] && [ condition ]; then
                    if command && [ condition ]; then

            1.5 整數條件句
                算術測試算符
                測試            比較
                =================================================================
                -lt                小於
                -le                小於或等於
                -eq                等於
                -ge                大於或等於
                -gt                大於
                -ne                不等於

        2. for
            for 迴圈可讓已以固定的次數<重複執行某個區段的程式碼
            語法:
                for name [in list ]
                do
                    用來處理 $name 的述句
                done
            list是一份名單(如果省略 in list,這份名單會被預設為"$@")