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