ユーザ用ツール

サイト用ツール


bash:01_control_statment

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
bash:01_control_statment [2014/06/05 06:23] matsuibash:01_control_statment [2020/06/28 00:07] (現在) matsui
行 1: 行 1:
 +====== 01 Bash - 制御文 ======
  
 +===== if文 =====
 +if文は、ある条件を指定して、それが真(0)が偽(1)かで処理を分岐する制御文です。\\
 +<color red>※else、elifは省略可能です。thenは必須となります。</color>
 +
 +==== 構文 ====
 +<code>
 +if [ 条件1 ]; または if test 条件
 +then
 +        条件1が成立した時に実行するコマンド
 +elif [ 条件2 ];
 +then
 +        条件1が不成立で条件2が成立した時に実行するコマンド
 +else
 +        条件1と条件2が不成立の時に実行するコマンド
 +fi
 +</code>
 +==== if文 使用例 ====
 +testコマンドによる、if分岐
 +
 +test01.sh
 +<code>
 +#!/bin/sh
 +
 +if test $1 -le 0
 +then
 +  echo "Number is Less than or equal 0."
 +else
 +  echo "Number is grater than 0."
 +fi
 +</code>
 +
 +実行例
 +<code console>
 +$ sh test01.sh 6
 +Number is Less than or equal 0.
 +$ sh test01.sh 8
 +Number is grater than 0.
 +</code>
 +===== 条件 =====
 +
 +^  ファイル形式のチェック  ^^
 +|-b  File|指定したFileがブロックデバイスファイルなら真である。 |
 +|-c  File|指定したFileがキャラクタデバイスファイルなら真である。|
 +|-d  File|指定したFileがディレクトリなら真である。|
 +|-f  File|指定したFileが通常ファイルなら真である。|
 +|-L  File|指定したFileがシンボリックリンクなら真である。|
 +|-p  File|指定したFileが名前付きパイプなら真である。|
 +|-S  File|指定したFileがソケットなら真である。|
 +
 +
 +^  ファイルパーミッションのチェック  ^^
 +|-g  File|指定したFileにSGIDがセットされていれば真である。|
 +|-k  File|指定したFileにスティッキービットがセットされていれば真である。|
 +|-r  File|指定したFileが読み取り可能なら真である。|
 +|-u  File|指定したFileにSUIDがセットされていれば真である。|
 +|-w  File|指定したFileが書き込み可能なら真である。|
 +|-x  File|指定したFileが実行可能なら真である。|
 +
 +^  その他のファイルのチェック  ^^
 +|-e  File|指定したFileが存在すれば真である。|
 +|-s  File|指定したFileのファイルサイズが0より大きければ真である。|
 +
 +^  文字列のチェック  ^^
 +|-n  文字列|文字列の長さが0より大きければ真である。|
 +|-z  文字列|文字列の長さが0であれば真である。|
 +|文字列1 = 文字列2|2つの文字列が等しければ真である。|
 +|文字列1 != 文字列2|2つの文字列が等しくなければ真である。|
 +
 +
 +^  数値のチェック  ^^ 英語略の意味 ^
 +|数値1  -eq  数値2|2つの数値が等しければ真である。|equal to|
 +|数値1  -ne  数値2|2つの数値が等しくなければ真である。|not equal to|
 +|数値1  -ge  数値2|数値1が数値2以上であれば真である。|greater than or equal to|
 +|数値1  -gt  数値2|数値1が数値2より大きいのであれば真である。|greater than|
 +|数値1  -le  数値2|数値1が数値2以下であれば真である。|less than or equal to|
 +|数値1  -lt  数値2|数値1が数値2未満であれば真である。|less than|
 +
 +
 +^  論理結合  ^^
 +|!条件|条件が偽であれば真である。|
 +|条件1 -a 条件2|条件1と条件2の両方が真であれば真である。(AND)|
 +|条件1 -o 条件2|条件1と条件2のどちらかが真であれば真である。(OR)|
 +
 +
 +===== for文 =====
 +for文は、同一の処理を何度も繰り返すループ文です。\\
 +引数の要素を順番に変数に渡していく事で、繰り返し処理に変化を付けます。\\
 +引数の要素がひととおり巡ったらforループを抜けます。\\
 +ループの回数は引数の要素数で決まります。
 +
 +==== 構文 ====
 +<code>
 +for 変数 in 引数・・・
 +do
 + 繰り返し実行されるコマンド
 +done
 +</code>
 +
 +==== for文 例1 ====
 +
 +for_test01.sh
 +<code>
 +#!/bin/sh
 +
 +for i in 0 1 2 3 4 5
 +do
 +  echo $i
 +done
 +</code>
 +
 +実行例
 +<code console>
 +$ ./for_test01.sh
 +0
 +1
 +2
 +3
 +4
 +
 +</code>
 +
 +
 +===== for文(C言語風) =====
 +bashではC言語で同じみの形式でfor文が使えます。\\
 +expr1を前提とし、条件expr2が成立するまで処理を繰り返し、その間expr3を実行するという形式です。
 +==== 構文 ====
 +
 +<code>
 +for (( expr1 ; expr2 ;expr3 ))
 +do
 + 繰り返し実行されるコマンド
 +done
 +</code>
 +
 +==== for文(C言語風) 例1 ====
 +
 +変数iを0として変数iが10より小さい間変数iに1づつ足していく。
 +
 +for _test02.sh
 +<code>
 +#!/bin/sh
 +
 +for (( i=0 ; i<10 ; i++ ))
 +do
 +  echo $i
 +done
 +</code>
 +
 +実行例
 +<code console>
 +$ ./for_test02.sh
 +0
 +1
 +2
 +3
 +4
 +5
 +6
 +7
 +8
 +9
 +</code>
 +===== while文 =====
 +while文は、ある条件を提示してその条件を満たしている間、同一の処理を何度も繰り返すループ文です。\\
 +while文は条件の終了状態が真である場合は doとdoneの間に記述されたコマンドを実行します。\\
 +そして条件の終了状態が偽になり次第ループから抜けます。
 +
 +==== 構文 ====
 +<code>
 +while 条件 
 +do 
 + 繰り返し実行されるコマンド
 +done
 +</code>
 +
 +==== 無限ループを使う ====
 +while文を使うと無限ループを簡単に作れます。\\
 +「いつも真」になるようにしてやれば、いいだけです。
 +
 +無限ループ記述例
 +^ 記述例 ^ 説明 ^
 +|while true; do . . . .|trueコマンドはいつも真(0)を返す|
 +|while [1]; do . . . .|「test 1」はいつも真(0)を返す|
 +|while :; do . . . .|コマンドは「何もしない」コマンド。終了コードは真(0)を返す。|
 +
 +
 +==== while文 使用例 ====
 +変数Aに1を入れておいて、while文の条件を10以下なら真にしておく\\
 + 変数Aが10以下であれば、「まだ10より小さい」と表示させる。\\
 + exprで変数Aに1づつ足しているので、変数Aが10になればwhile文を抜ける。
 +
 +while_test01.sh
 +<code>
 +#!/bin/sh
 +A=1
 +while [ $A -lt 10 ]
 +do
 +  echo "まだ10より小さい"
 +  A=`expr $A + 1`
 +done
 +echo "10を超えました。"
 +</code>
 +
 +実行例
 +<code>
 +$ ./while_test01.sh 
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +まだ10より小さい
 +10を超えました。
 +</code>
 +
 +=== リモートホストにpingを送り続ける ===
 +while_test02.sh
 +<code>
 +#!/bin/sh
 +HOST="example.jp"
 +INTERVAL=600
 +
 +while true
 +do
 +  echo %%%%%
 +  date
 +  ping -c1 $HOST
 +  echo %%%%%
 +  sleep $INTERVAL
 +done
 +</code>
 +
 +実行例 10分おきに実行し続ける。
 +<code console>
 +$ ./while_test02.sh
 +%%%%%
 +2006年 6月21日 水曜日 23時28分03秒 JST
 +PING dynabook.mydomain.co.jp (192.168.1.11): 56 data bytes
 +64 bytes from 192.168.1.11: icmp_seq=0 ttl=64 time=0.751 ms
 +
 +--- dynabook.mydomain.co.jp ping statistics ---
 +1 packets transmitted, 1 packets received, 0% packet loss
 +round-trip min/avg/max/stddev = 0.751/0.751/0.751/0.000 ms
 +%%%%%
 +%%%%%
 +2006年 6月21日 水曜日 23時38分03秒 JST
 +PING dynabook.mydomain.co.jp (192.168.1.11): 56 data bytes
 +64 bytes from 192.168.1.11: icmp_seq=0 ttl=64 time=0.751 ms
 +
 +--- dynabook.mydomain.co.jp ping statistics ---
 +1 packets transmitted, 1 packets received, 0% packet loss
 +round-trip min/avg/max/stddev = 0.751/0.751/0.751/0.000 ms
 +%%%%%
 +%%%%%
 +2006年 6月21日 水曜日 23時48分03秒 JST
 +PING dynabook.mydomain.co.jp (192.168.1.11): 56 data bytes
 +64 bytes from 192.168.1.11: icmp_seq=0 ttl=64 time=0.751 ms
 +
 +--- dynabook.mydomain.co.jp ping statistics ---
 +1 packets transmitted, 1 packets received, 0% packet loss
 +round-trip min/avg/max/stddev = 0.751/0.751/0.751/0.000 ms
 +%%%%%
 +</code>
 +
 +
 +== while文 ファイルの内容を行単位で読み込む ==
 +
 +while文を使うと、ファイルからデータを順番に読み込みながら、そのファイルが終了するまでループするという処理ができます。\\
 +この機能は非常に便利なので覚えておくといいでしょう。
 +
 +構文(fileから読み込みfileの行が終わるまでループします。)
 +<code>
 +while read LINE
 +do
 +  ・(ループ処理)
 +  ・(ループ処理)
 +  ・(ループ処理)
 +done < file
 +</code>
 +
 +
 +
 +
 +test.txtを一行づつ読み込みechoコマンドで標準出力に出力します。
 +while_test03.sh
 +
 +<code>
 +#!/bin/sh
 +FILE=test.txt
 +while read LINE
 +do
 + echo $LINE
 +done < $FILE
 +</code>
 +
 +test.txtの内容は下記のようになっています。
 +<code>
 +$ cat test.txt 
 +
 +
 +
 +
 +
 +
 +
 +</code>
 +
 +実行するとこのように一行ずつ表示されます。
 +<code>
 +$ ./while_test03.sh
 +
 +
 +
 +
 +
 +
 +
 +</code>
 +
 +
 +===== case文 =====
 +
 +case文は、文字列がパターンと合致するかによって分岐する制御文です。\\
 +if文を駆使すれば同様の処理も可能ですが、文字列に対する複数の分岐を考える場合はcase文の方がわかりやすく融通もききます。\\
 +合致するパターンがあれば、)から;;までに指定されているコマンド行を実行します。\\
 +通常は、パターンの最後には*(ワイルドカード)を指定し、どのパターンにも合致しなかった場合の処理を書いておきます。\\
 +case文の終了は綴りを逆さまにしたesacです。
 +
 +==== 構文 ====
 +<code>
 +case string in
 +  pattern_1)
 +    commands1
 +  ;;
 +  pattern_2)
 +    commands2
 +  ;;
 +esac
 +</code>
 +
 +==== case文で使用するパターン例 ====
 +^ 表現の形式 ^ 意味 ^
 +|string)|stringという文字列そのもの|
 +|string1|string2)|string1あるいはstring2という文字列|
 +|str*)|先頭がstrの文字列|
 +|*str)|末尾がstrの文字列|
 +|[a-z]*)|先頭がアルファベット小文字|
 +|[!0-9]*)|先頭が数字以外の文字列|
 +|[yY]|yかY|
 +|???)|3文字の文字列|
 +|*)|すべて|
 +
 +
 +==== case分 例1 ====
 +case_test01.sh
 +<code>
 +#!/bin/sh
 +
 +case $1 in
 +    [a-z]*)
 +       echo "アルファベット小文字で始まってます。"
 +    ;;
 +    [A-Z]*)
 +       echo "アルファベット大文字で始まってます。"
 +    ;;
 +    [0-9]*)
 +       echo "数字で始まってます。"
 +    ;;
 +esac
 +</code>
 +
 +実行例
 +<code console>
 +$ ./case_test01.sh snoopy
 +アルファベット小文字で始まってます。
 +
 +$ ./case_test01.sh Apple
 +アルファベット大文字で始まってます。
 +
 +$ ./case_test01.sh 1999
 +数字で始まってます。
 +</code>
 +
 +==== case文 例2 キーボードからの入力で処理を分ける ====
 +case_test02.sh
 +<code>
 +#!/bin/sh
 +
 +echo -n "Please enter Yes or No _"
 +read RESPONSE
 +
 +case $RESPONSE in
 +         [Yy][Ee][Ss])  echo "You answered Yes." ;;
 +         [Nn][Oo])      echo "You ansered No." ;;
 +          *)            echo "Please enter Yes or No." ;;
 +esac
 +</code>
 +
 +実行例
 +<code console>
 +$ ./case_test02.sh
 +Please enter Yes or No _Yes
 +You ansered Yes.
 +
 +$ ./case_test02.sh
 +Please enter Yes or No _No
 +You ansered No.
 +
 +AAAと入力した場合、どれにも合致しないので、*の行に当てはまる。
 +$ ./case_test02.sh
 +Please enter Yes or No _AAA
 +Please enter Yes or No.
 +</code>
 +
 +===== select文 =====
 +select文はbashで追加となった制御文です。\\
 +項目をリストし、番号を選んで処理させるというメニュー形式の対話的な画面が簡単に作れます。\\
 +case文でも同じようなメニュー画面を作成することもできますが、大掛かりなスクリプトになってしまいます。\\
 +select文を使うとメニュー画面を簡単に作成できるメリットがあります。
 +
 +==== 構文 ====
 +<code>
 +select variable in menulists
 +do
 +  commands
 +done
 +</code>
 +
 +==== select分 例1 ====
 +<color red>
 +※select文の場合は必ずbashを指定しなければなりません。\\
 + ×#!/bin/sh ○#!/bin/bash
 +</color>
 +
 +select_test01.sh
 +<code>
 +#!/bin/bash
 +
 +select i in Item1 Item2 Item3
 +do
 +  echo "You entered $i."
 +done
 +</code>
 +
 +
 +実行例
 +<code console>
 +$ ./select_test01.sh
 +1)Item1            ←メニューが現れる
 +2)Item2
 +3)Item3
 +#? 1               ←#?で入力待ちになる。
 +You entered Item1.
 +</code>
 +
 +===== continueコマンド =====
 +for文やwhile文などの処理を途中で中断し、処理をループの先頭に戻すコマンドがcontinueです。\\
 +書式もbreakコマンドと同じで、いくつ前のループ文の先頭へ戻るかを引数で渡せます。
 +
 +==== 構文 ====
 +
 +<code>
 +continue 実行を継続したいループまでの深さ
 +</code>
 +
 +==== continueコマンド 例1 ====
 +
 +以下のようにfor文が3つのネストになっている場合2を指定すると"for a"のループから実行を継続します。
 +<code>
 +#!/bin/sh
 +for a
 +do
 + for b
 + do
 + for c
 + do
 + if [ $c = redhat ];
 + then
 + continue 2
 + fi
 + done
 + done
 +done
 +</code>
 +
 +===== breakコマンド =====
 +for文やwhile文から強制的に抜けるコマンドがbreakコマンドです。\\
 +もちろんselect文やuntil文からも抜け出せます。\\
 +continueコマンドがループの先頭に戻るのに対し、breakコマンドはループを抜けます。\\
 +breakコマンドは、引数がないとループ文を1つだけ抜けます。\\
 +ネストした複数のループを一挙に抜けたいときは、いくつのループを抜けるかという数を引数として指します。\\
 +※引数に指定した数値の方がループのネストより多かったときは一番上位のループを抜けますが、エラーにはなりません。
 +
 +==== 構文 ====
 +<code>
 +break 抜けたいループの深さ
 +</code>
 +
 +==== breakコマンド 例1 ====
 +
 +以下のようにfor文が3つのネストになっている場合3を指定すると全てのループから抜けます。
 +<code>
 +#!/bin/sh
 +
 +for a
 +do
 + for b
 + do
 + for c
 + do
 + break 3
 + done
 + done
 +done
 +</code>
 +
 +
 +{{tag>bash:syntax bash}}