一、小括弧、丸括弧 ()

1、単一の小括弧 ()

  • コマンドグループ。括弧内のコマンドは新しいサブシェルを起動して順次実行されるため、括弧内の変数はスクリプトの残りの部分では使用できない。括弧内の複数のコマンドはセミコロンで区切り、最後のコマンドにはセミコロンがなくてもよい。各コマンドと括弧の間にはスペースを入れる必要はない。
  • コマンド置換。`cmd`と同等であり、shellはコマンドラインをスキャンして$(cmd)構造を見つけると、$(cmd)内のcmdを一度実行し、その標準出力を取得して、この出力を元のコマンドに置く。tcshなど一部のshellではサポートされていない。
  • 配列の初期化に使用する。例:array=(a b c d)

2、二重の小括弧 (( ))

  • 整数拡張。この拡張計算は整数型の計算であり、浮動小数点型はサポートされない。((exp))構造は算術式の値を展開して計算する。式の結果が0の場合、返される終了ステータスコードは1、すなわち「偽」となり、非ゼロの式が返す終了ステータスコードは0、すなわち「真」となる。論理判断の場合、式expが真なら1、偽なら0である。
  • 括弧内の演算子や式がC言語の演算規則に適合していれば、$((exp))内で使用でき、三項演算子でさえも使用できる。異なる進数(2進数、8進数、16進数など)の演算を行う場合、出力結果はすべて自動的に10進数に変換される。例:echo $((16#5f)) の結果は95(16進数から10進数へ変換)
  • (( )) を単独で使用して変数の値を再定義することもできる。例えば a=5; ((a++)) で $a を6に再定義できる。
  • 主に算術演算の比較に使用される。二重括弧内の変数には$記号のプレフィックスを付けなくてもよい。括弧内では複数の式をカンマで区切って記述できる。括弧内の式がC言語の演算規則に適合していれば、例えばfor((i=0;i<5;i++))を直接使用できる。二重括弧を使用しない場合、for i in `seq 0 4` または for i in {0..4} となる。また、if (($i<5)) を直接使用でき、二重括弧を使用しない場合は if [ $i -lt 5 ] となる。

二、角括弧 []

1、単一の角括弧 []

  • bashの内部コマンドであり、[ と test は同等である。絶対パスで指定しない場合、通常はbashに組み込みのコマンドを使用する。if/test構造における左の角括弧はtestを呼び出すコマンドの識別子であり、右の角括弧は条件判断を閉じるものである。このコマンドはその引数を比較式またはファイルテストとして扱い、比較結果に基づいて終了ステータスコードを返す。if/test構造では右の角括弧は必須ではないが、新しいバージョンのBashでは必須とされている。
  • Testと[]で使用できる比較演算子は==と!=のみであり、どちらも文字列比較に使用され、整数比較には使用できない。整数比較では-eqや-gtのような形式のみ使用できる。文字列比較でも整数比較でも、大なり記号や小なり記号はサポートされない。どうしても使用したい場合、文字列比較ではエスケープ形式を使用できる。"ab"と"bc"を比較する場合:[ ab \< bc ] は真となり、つまり戻りステータスは0となる。[ ]内の論理積と論理和は -a と -o で表す。
  • 文字範囲。正規表現の一部として使用され、一致する文字の範囲を記述する。test用途としての角括弧内では正規表現を使用できない。
  • array構造のコンテキストでは、角括弧は配列の各要素の番号を参照するために使用される。

2、二重角括弧 [[ ]]

  • [[ は bash プログラミング言語のキーワードである。コマンドではなく、[[ ]] 構造は [ ] 構造よりも汎用性が高い。[[ と ]] の間のすべての文字では、ファイル名展開やワード分割は発生しないが、パラメータ展開とコマンド置換は発生する。
  • 文字列のパターンマッチングをサポートし、=~演算子を使用するとshellの正規表現もサポートする。文字列比較の際、右側を単なる文字列ではなくパターンとして扱うことができる。例えば[[ hello == hell? ]] は真となる。[[ ]] 内で文字列やワイルドカードをマッチングする場合、引用符は不要である。
  • [[ ... ]] 条件判断構造を [ ... ] の代わりに使用すると、スクリプト内の多くの論理エラーを防ぐことができる。例えば、&&、||、<、> 演算子は [[ ]] 条件判断構造内では正常に使用できるが、[ ] 構造内に現れるとエラーになる。例えば if [[ $a != 1 && $a != 2 ]] を直接使用できる。二重括弧を使用しない場合、if [ $a -ne 1] && [ $a != 2 ] または if [ $a -ne 1 -a $a != 2 ] となる。
  • bashは二重角括弧内の式を単一の要素として扱い、終了ステータスコードを返す。
if ($i<5)    
if [ $i -lt 5 ]    
if [ $a -ne 1 -a $a != 2 ]    
if [ $a -ne 1] && [ $a != 2 ]    
if [[ $a != 1 && $a != 2 ]]    
     
for i in $(seq 0 4);do echo $i;done    
for i in `seq 0 4`;do echo $i;done    
for ((i=0;i<5;i++));do echo $i;done    
for i in {0..4};do echo $i;done    

三、中括弧、波括弧 {}

1、通常の使い方

(1) 波括弧展開。(グロビング)は波括弧内のファイル名を展開する。波括弧内では、空白が引用符で囲まれるかエスケープされない限り、空白は許可されない。1つ目:波括弧内のカンマ区切りのファイルリストを展開する。例:touch {a,b}.txt の結果は a.txt b.txt。2つ目:波括弧内のピリオド2つ(..)で区切られた連番ファイルリストを展開する。例:touch {a..d}.txt の結果は a.txt b.txt c.txt d.txt

# ls {ex1,ex2}.sh    
ex1.sh  ex2.sh    
# ls {ex{1..3},ex4}.sh    
ex1.sh  ex2.sh  ex3.sh  ex4.sh    
# ls {ex[1-3],ex4}.sh    
ex1.sh  ex2.sh  ex3.sh  ex4.sh    

(2) コードブロック。内部グループとも呼ばれ、この構造は事実上匿名関数を作成する。小括弧内のコマンドとは異なり、波括弧内のコマンドは新しいサブシェルを起動して実行しない。つまり、スクリプトの残りの部分でも括弧内の変数を使用できる。括弧内のコマンドはセミコロンで区切り、最後のコマンドにもセミコロンが必要である。{}の最初のコマンドと左括弧の間にはスペースが必要である。

2、いくつかの特殊な置換構造

${var:-string} 
${var:+string} 
${var:=string}
${var:?string}

1、${var:-string}と${var:=string}:変数varが空の場合、コマンドラインで${var:-string}をstringで置き換える。varが空でない場合は、${var:-string}を変数varの値で置き換える。${var:=string}の置換規則は${var:-string}と同じであるが、異なる点は、${var:=string}はvarが空の場合にstringで${var:=string}を置き換えると同時に、stringを変数varに代入する点である。${var:=string}のよく使われる用法は、変数が代入されているかどうかを判断し、代入されていなければデフォルト値を代入するというものである。

2、${var:+string}の置換規則は上記とは逆で、varが空でない場合にのみstringに置き換える。varが空の場合は置き換えず、または変数varの値、すなわち空値に置き換えると言うこともできる。(変数varがこのとき空であるため、この2つの言い方は等価である)

3、${var:?string}の置換規則:変数varが空でない場合、${var:?string}を変数varの値で置き換える。変数varが空の場合、stringを標準エラーに出力してスクリプトを終了する。この特性を利用して、変数の値が設定されているかどうかを確認できる。

補足拡張:上記の5つの置換構造において、stringは必ずしも定数である必要はなく、別の変数の値やコマンドの出力を使用できる。

3、4種類のパターンマッチ置換構造

パターンマッチの覚え方:

# は左側を取り除く(キーボード上で#は$の左側にある)
% は右側を取り除く(キーボード上で%は$の右側にある)

#と%の単一記号は最小マッチ、同じ記号を2つ並べたものは最大マッチである。

${var%pattern}
${var%%pattern
${var#pattern}
${var##pattern}
  • 1つ目のパターン:${variable%pattern}。このパターンでは、shellはvariableを調べ、指定されたパターンpatternで終わっているかどうかを確認する。もし終わっていれば、コマンドラインからvariableの内容の右側にある最短のマッチパターンを削除する。
  • 2つ目のパターン:${variable%%pattern}。このパターンでは、shellはvariableを調べ、指定されたパターンpatternで終わっているかどうかを確認する。もし終わっていれば、コマンドラインからvariableの内容の右側にある最長のマッチパターンを削除する。
  • 3つ目のパターン:${variable#pattern}。このパターンでは、shellはvariableを調べ、指定されたパターンpatternで始まっているかどうかを確認する。もし始まっていれば、コマンドラインからvariableの内容の左側にある最短のマッチパターンを削除する。
  • 4つ目のパターン:${variable##pattern}。このパターンでは、shellはvariableを調べ、指定されたパターンpatternで終わっているかどうかを確認する。もし終わっていれば、コマンドラインからvariableの内容の右側にある最長のマッチパターンを削除する。
  • この4つのモードではいずれもvariableの値は変更されない。そのうち、patternで*マッチング記号を使用した場合のみ、%と%%、#と##に違いが生じる。構造内のpatternはワイルドカードをサポートしており、*は0個以上の任意の文字を表し、?は1つの任意の文字のみにマッチし、[...]は角括弧内の文字にマッチし、[!...]は角括弧内の文字にマッチしないことを表す。
# var=testcase    
# echo $var    
testcase    
# echo ${var%s*e}   
testca    
# echo $var    
testcase   
# echo ${var%%s*e}   
te  
# echo ${var#?e}    
stcase  
# echo ${var##?e}    
stcase  
# echo ${var##*e}    
  
# echo ${var##*s}    
e    
# echo ${var##test}    
case    

4、文字列の抽出と置換

${var:num}
${var:num1:num2}
${var/pattern/pattern}
${var//pattern/pattern}
  • 1つ目のモード:${var:num}。このモードでは、shellはvar内のnum番目の文字から末尾までのすべての文字を抽出する。numが正の数の場合、左の0から開始する。numが負の数の場合、右から部分文字列を抽出するが、コロンの後にスペース、数字、またはnum全体を括弧で囲む必要がある。例:${var: -2}、${var:1-3}、${var:(-2)}。
  • 2つ目のモード:${var:num1:num2}。num1は位置、num2は長さである。$var文字列の$num1番目の位置から長さ$num2の部分文字列を抽出することを示す。負の数は指定できない。
  • 3つ目のモード:${var/pattern/pattern}は、var文字列内で最初にマッチしたpatternを別のpatternに置換することを示す。
  • 4つ目のモード:${var//pattern/pattern}は、var文字列内のすべてのマッチするpatternを別のpatternに置換することを示す。
[root@centos ~]# var=/home/centos  
[root@centos ~]# echo $var  
/home/centos  
[root@centos ~]# echo ${var:5}  
/centos  
[root@centos ~]# echo ${var: -6}  
centos  
[root@centos ~]# echo ${var:(-6)}  
centos  
[root@centos ~]# echo ${var:1:4}  
home  
[root@centos ~]# echo ${var/o/h}  
/hhme/centos  
[root@centos ~]# echo ${var//o/h}  
/hhme/cenths  

四、記号$の後の括弧

  • (1)${a} は変数aの値。曖昧さを生じない場合は中括弧を省略できる。
  • (2)$(cmd) はコマンド置換であり、`cmd`と同じ効果を持つ。結果はshellコマンドcmdの出力である。ただし、一部のShellバージョンでは$()形式のコマンド置換をサポートしていない(例:tcsh)。
  • (3)$((expression)) は`expr expression`と同じ効果を持つ。数学式expの数値を計算する。ここでexpはC言語の演算規則に適合していればよく、三項演算子や論理式であっても計算できる。

五、使用

  • 1、複数コマンドの実行

    • (1)単一の小括弧 (cmd1;cmd2;cmd3) は、新しい子シェルを開いてコマンドcmd1、cmd2、cmd3を順番に実行する。各コマンドはセミコロンで区切り、最後のコマンドの後にセミコロンは不要である。
    • (2)単一の中括弧 { cmd1;cmd2;cmd3;} は、現在のシェルでコマンドcmd1、cmd2、cmd3を順番に実行する。各コマンドはセミコロンで区切り、最後のコマンドの後にはセミコロンが必要である。最初のコマンドと左括弧の間にはスペースを空けなければならない。

    に対して{}と()括弧内のリダイレクト記号はそのコマンドのみに影響するが、括弧外のリダイレクト記号は括弧内のすべてのコマンドに影響する。

    原文出典:http://blog.csdn.net/taiyang1987912/article/details/39551385