【shellノート>スクリプト】構造化コマンドを使用した条件制御

9332 ワード

内容
  • if-then文を使用
  • ネストif文
  • testコマンド
  • 複合条件試験
  • 両方の括弧と二重括弧を使用
  • caseコマンド
  • 多くのプログラムではshellスクリプトのコマンドにいくつかの論理フロー制御を適用する必要があります.いくつかのコマンドは、条件に基づいて対応するコマンドを実行すると判断します.このようなコマンドは、通常、構造化コマンドと呼ばれます.概念的に理解すると、構造化コマンドはshellスクリプトの論理構造であり、shellスクリプトを順次実行するのではなく、複雑なタスク要件に対応するためにコマンドを組織的に実行する.
    if-then文
    最も基本的な構造化コマンドはif-then文で、そのフォーマットは以下の通りです.
    if command
    then 
        commands
    fi
    

    なお、他のプログラミング言語では、if文の後のオブジェクトは等式であり、等式の結果はTRUEまたはFALSEであるが、bash shellのif文はif文の後の命令であり、その命令の終了ステータスコードが0(命令成功実行)であればthen文の後の命令を実行する.fi表示if文はこれで終わります.
    簡単な例を次に示します.
    wsx@wsx-ubuntu:~/script_learn$ cat test1.sh 
    #! /bin/bash
    # testing the if statement
    if pwd
    then 
        echo "It worked"
    fi
    
    wsx@wsx-ubuntu:~/script_learn$ chmod u+x test1.sh 
    wsx@wsx-ubuntu:~/script_learn$ ./test1.sh 
    /home/wsx/script_learn
    It worked
    

    この例では、pwdコマンドの実行に成功したと判断した後、出力テキスト文字列を実行する.pwdコマンドを勝手に打つ文字に変更してみてください.エラーメッセージが表示され、then以降の文も実行されません.
    if-then文の別の形式:
    if command; then
    commands
    fi
    

    thenセクションでは、複数のコマンドを使用できます(フォーマットのcommandの末尾にsがあるかどうかもわかります).
    もう1つの例では、if文でgrepコマンドを使用して/etc/passwdファイルでユーザー名が現在システムで使用されているかどうかを検索します.ユーザーがログイン名を使用している場合、スクリプトにはテキスト情報が表示され、そのユーザーHOMEディレクトリのbashファイルがリストされます.
    wsx@wsx-ubuntu:~/script_learn$ cat test3.sh 
    #!/bin/bash
    # testing multiple commands in the then section
    # 
    testuser=wsx
    #
    if grep $testuser /etc/passwd
    then
      echo "This is my first command"
      echo "This is my second command"
      echo "I can even put in other commands besides echo:"
      ls -a /home/$testuser/.b*
    fi
    
    wsx@wsx-ubuntu:~/script_learn$ chmod u+x test3.sh 
    wsx@wsx-ubuntu:~/script_learn$ ./test3.sh 
    wsx:x:1000:1000:wsx,,,:/home/wsx:/bin/bash
    This is my first command
    This is my second command
    I can even put in other commands besides echo:
    /home/wsx/.bash_history  /home/wsx/.bashrc
    /home/wsx/.bash_logout   /home/wsx/.bashrc-anaconda3.bak
    
    

    設定したユーザー名が存在しない場合は、出力されません.では、ここに表示されるメッセージの一部が、ユーザー名がシステムに見つからないことを示している場合、より友好的になる可能性があります.では、if-then-else文を見てみましょう.
    if-then-else文
    意味は非常に理解しやすいと信じています.ここでは、elseのコマンドが正常に実行されなかったステップを処理するためにifブロックを追加しました.書式:
    if command
    then 
      commands
    else commands
    fi
    

    ネストif
    スクリプトコードの複数の条件を確認する必要がある場合があります.ネストされたif-then文を使用することができます.
    処理の一例:/etc/passwdファイルにユーザー名が存在するかどうか、およびそのユーザー名のディレクトリが存在するかどうかを確認します.
    wsx@wsx-ubuntu:~/script_learn$ cat test5.sh 
    #!/bin/bash
    
    # Testing nested ifs
    #
    testuser=NoSuchUser
    #
    if grep $testuser /etc/passwd
    then 
      echo "The user $testuser exits on this system."
    else 
      echo "The user $testuser does not exit on this system."
      if ls -d /home/$testuser/
      then
         echo "However, $testuser has a directory."
      fi
    fi
    
    wsx@wsx-ubuntu:~/script_learn$ chmod u+x test5.sh 
    wsx@wsx-ubuntu:~/script_learn$ ./test5.sh 
    The user NoSuchUser does not exit on this system.
    ls:     '/home/NoSuchUser/':          
    
    else部分の別の形式:elifを使用することができる.これにより、複数のif-then文を書くことはなくなります.他の言語では、elifの形式を使うものもあれば、else ifなどの形式を使うものもあります.同じように異なる言語に含まれる異なる表現に直面して、接触するものが多くなると、さまざまな言語コードが直列に書かれないように意識的に区別する必要があります.
    if command1
    then
        commands
    elif command2
    then 
        more commands
    fi
    

    この表現は論理的にはっきりしているが、書く人を混乱させやすい.実際には、1つのifが1つのfiに対応していることがわかります.これは大きなネストif構造です.elif文のうち、直後のelse文はelifコードブロックであり、if-thenコードブロックではないことを覚えておいてください.
    testコマンド
    ここまで、ifの後に付いているのは普通のshellコマンドであることはよく知られていますが、他の条件をテストする必要があります.testコマンドは、if-then文で異なる条件をテストする方法を提供します.testコマンドにリストされている条件が成立すると、testコマンドは終了し、ステータスコード0に戻ります.このようにif-then文は、他のプログラミング言語のif-then文と同様に動作する.
    testコマンドフォーマット:
    test condition  
    
    conditionは、testコマンドがテストする一連のパラメータと値です.このconditionを書かないと、testは0以外を返し、if文はelseにジャンプして実行されます.
    bash shellは、if-then文でtestコマンドを宣言する必要がない条件テスト方法を提供します.
    if [ condition ]
    then commands
    fi
    

    これは私たちの他のプログラミング習慣に非常に近い.この方法をお勧めします.testコマンドを使用する場合は、さまざまな条件パラメータを覚えておく必要があります.
    数値比較
    比較
    説明
    n1 -eq n2
    (n 1)は(n 2)に等しい
    n1 -ge n2
    以上
    n1 -gt n2
    より大きい
    n1 -le n2
    以下
    n1 -lt n2
    より小さい
    n1 -ne n2
    等しくない
    文字列の比較
    比較
    説明
    str1 = str2
    (str 1とstr 2の比較)同じ
    str1 != str2
    異なる
    str1 < str2
    小さい
    str1 > str2
    大きい
    -n str1
    string 1の長さが0でないことを確認します
    -z str1
    string 1の長さが0であるかどうかを確認します
    大きいサイズと小さいサイズは、エスケープする必要があります.順序の大きいコマンドと小さいコマンドとsortコマンドの違い.
    ファイル比較
    比較
    説明
    -d file
    fileが存在し、ディレクトリであるかどうかを確認します.
    -e file
    ~存在するかどうか
    -f file
    ~存在するか、ファイルであるか
    -r file
    ~存在するか、読み取り可能か
    -s file
    ~存在するかどうかは空ではない
    -w file
    ~存在するか、書き込み可能か
    -x file
    ~存在するか実行可能か
    -O file
    ~現在のユーザーが所有しているかどうか
    -G file
    ~存在するか、デフォルトグループは現在のユーザーと同じか
    file1 -nt file2
    file 1がfile 2より新しいかどうかを確認します
    file1 -ot file2
    file 1がfile 2より古いかどうかを確認します
    ふくごうじょうけんしけんif-then文を使用すると、ブールロジックを使用してテストを組み合わせることができます.使用可能
  • [ condition1] && [ condition2]
  • [ condition1] || [ condition2]

  • if-thenの高度な特性
  • 数式用二重かっこ
  • 高度な文字列処理機能に使用される両方のかっこ
  • 二重かっこ
    コマンド形式:
    (( expresiion ))
    
    expressionは、任意の数学的付与または比較式であってもよい.testコマンドで使用される標準数学演算子に加えて、以下にいくつかの他のものを示します.
    アイコン
    説明
    val++
    後増
    val --
    あとげん
    ++ val
    先増
    -- val
    先減
    !
    ろんりしゅうらん
    ~
    位求反
    **
    べき乗演算
    <<
    左シフト
    >>
    右シフト
    &
    ビットブール和
    |
    ビットブールまたは
    &&
    論理和
    ||
    論理または
    例を見てみましょう
    wsx@wsx-ubuntu:~/script_learn$ cat test23.sh 
    #!/bin/bash
    # using doble parenthesis
    #
    val1=10
    #
    if (( $val1 ** 2 > 90 ))
    then
      (( val2 = $val1 ** 2 ))
      echo "The square of $val1 is $val2"
    fi
    
    wsx@wsx-ubuntu:~/script_learn$ chmod u+x test23.sh 
    wsx@wsx-ubuntu:~/script_learn$ ./test23.sh 
    The square of 10 is 100
    
    

    両方のかっこ
    両方のカッココマンドは、文字列の比較に関する高度な特性を提供します.コマンドのフォーマットは次のとおりです.
    [[ expression ]]
    

    両方の括弧内のexpressiontestコマンドで使用される標準文字列比較を使用します.しかし、testは、モードマッチングという特性を提供していない.
    パターンマッチングでは、文字列値に一致する正規表現を定義できます.
    wsx@wsx-ubuntu:~/script_learn$ cat test24.sh 
    #! /bin/bash
    # using pattern matching
    # 
    if [[ $USER == r* ]]
    then
      echo "Hello $USER"
    else 
      echo "Sorry, I do not know you"
    fi
    
    wsx@wsx-ubuntu:~/script_learn$ chmod u+x test24.sh
    wsx@wsx-ubuntu:~/script_learn$ ./test24.sh 
    Sorry, I do not know you
    

    前のスクリプトでは、2等号を使用しました.2等号は、右側の文字列を1つのモードと見なし、モードマッチングルールを適用します.
    ケースコマンドcaseコマンドがあれば、すべてのelif文を書き出して同じ変数の値をチェックする必要はありません.caseコマンドは、リスト形式で単一変数の多値をチェックします.
    次の2つのスクリプトの同じ機能を比較します.
    if文:
    wsx@wsx-ubuntu:~/script_learn$ cat test25.sh
    #!/bin/bash
    # looking for a possible value
    # 
    if [ $USER = "rich" ]
    then
      echo "Welcome $USER"
      echo "Please enjoy you visit"
    elif [ $USER = "barbara" ]
    then
      echo "Welcome $USER"
      echo "Please enjoy you visit"
    elif [ $USER = "testing" ]
    then
      echo "Special testing account"
    elif [ $USER = "jessica" ]
    then
      echo "Do not forget to logout when you're done"
    

    ケース文:
    case variable in
    pattern1 | pattern2) commands1;;
    pattern3) commands2;;
    *) default commands;;
    esac
    

    上記の例は、case文で表すことができる.
    wsx@wsx-ubuntu:~/script_learn$ cat test26.sh
    #!/bin/bash
    # using the case command
    #
    case $USER in
    rich | barbara)
      echo "Welcome, $USER"
      echo "Please enjoy your visits";;
    testing)
      echo "Special testing account";;
    jessica)
      echo "Do not forget to log off whe you're done";;
    *)
      echo "Sorry, you are not allowed here";;
    esac
    
    wsx@wsx-ubuntu:~/script_learn$ chmod u+x test26.sh 
    wsx@wsx-ubuntu:~/script_learn$ ./test26.sh
    Sorry, you are not allowed here
    
    
    caseコマンドは、指定した変数を異なるモードと比較します.変数とモードが一致する場合、shellはそのモードに指定したコマンドを実行します.縦線オペレータで複数のモードを1行で区切ることができます.アスタリスクは、既知のモードと一致しないすべての値を取得します.二重セミコロンの使用に注意してください.
    小結
    最も基本的なコマンドはif-then文です.
    拡張可能if-then文はif-then-else文です.if-then-else文はelif文で接続できます.
    スクリプトでは、数値、文字列の内容、ファイル、ディレクトリの状態など、コマンドではなく条件をテストする必要があります.testコマンドは簡単な方法を提供します.
    かっこはtestコマンドが統一された特殊bashコマンドである.
    二重括弧は別のオペレータを使用して高度な数学演算を行い、双方の括弧は高度な文字列モードマッチング演算を許可する.caseコマンドは、複数のif-then-elseコマンドを実行する簡単な方法であり、1つの値リストを参照して1つの変数の値をチェックします.
    構造化命令でのループについては,次回整理するノートで述べる.