ユーザ用ツール

サイト用ツール


サイドバー

このページの翻訳:



最近の更新



Tag Cloud

bash:01_control_statment

文書の過去の版を表示しています。


01 Bash - 制御文

if文

if文は、ある条件を指定して、それが真(0)が偽(1)かで処理を分岐する制御文です。

※else、elifは省略可能です。thenは必須となります。

構文

if [ 条件1 ]; または if test 条件
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 "Number is Less than or equal 0."
else
  echo "Number is grater than 0."
fi

実行例

$ 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 = 文字列22つの文字列が等しければ真である。
文字列1 != 文字列22つの文字列が等しくなければ真である。
数値のチェック 英語略の意味
数値1 -eq 数値22つの数値が等しければ真である。equal to
数値1 -ne 数値22つの数値が等しくなければ真である。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ループを抜けます。

ループの回数は引数の要素数で決まります。

構文

for 変数 in 引数・・・
do
	繰り返し実行されるコマンド
done

for文 例1

for_test01.sh

#!/bin/sh

for i in 0 1 2 3 4 5
do
  echo $i
done

実行例

$ ./for_test01.sh
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

実行例

$ ./for_test02.sh
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 "まだ10より小さい"
  A=`expr $A + 1`
done
echo "10を超えました。"

実行例

$ ./while_test01.sh 
まだ10より小さい
まだ10より小さい
まだ10より小さい
まだ10より小さい
まだ10より小さい
まだ10より小さい
まだ10より小さい
まだ10より小さい
まだ10より小さい
10を超えました。

リモートホストにpingを送り続ける

while_test02.sh

#!/bin/sh
HOST="example.jp"
INTERVAL=600

while true
do
  echo %%%%%
  date
  ping -c1 $HOST
  echo %%%%%
  sleep $INTERVAL
done

実行例 10分おきに実行し続ける。

$ ./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
%%%%%
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 
月
火
水
木
金
土
日

実行するとこのように一行ずつ表示されます。

$ ./while_test03.sh
月
火
水
木
金
土
日

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
???)3文字の文字列
*)すべて

case分 例1

case_test01.sh

#!/bin/sh

case $1 in
    [a-z]*)
       echo "アルファベット小文字で始まってます。"
    ;;
    [A-Z]*)
       echo "アルファベット大文字で始まってます。"
    ;;
    [0-9]*)
       echo "数字で始まってます。"
    ;;
esac

実行例

$ ./case_test01.sh snoopy
アルファベット小文字で始まってます。

$ ./case_test01.sh Apple
アルファベット大文字で始まってます。

$ ./case_test01.sh 1999
数字で始まってます。

case文 例2 キーボードからの入力で処理を分ける

case_test02.sh

#!/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

実行例

$ ./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.

select文

select文はbashで追加となった制御文です。

項目をリストし、番号を選んで処理させるというメニュー形式の対話的な画面が簡単に作れます。

case文でも同じようなメニュー画面を作成することもできますが、大掛かりなスクリプトになってしまいます。

select文を使うとメニュー画面を簡単に作成できるメリットがあります。

構文

select variable in menulists
do
  commands
done

select分 例1

※select文の場合は必ずbashを指定しなければなりません。
 ×#!/bin/sh ○#!/bin/bash

select_test01.sh

#!/bin/bash

select i in Item1 Item2 Item3
do
  echo "You entered $i."
done

実行例

$ ./select_test01.sh
1)Item1            ←メニューが現れる
2)Item2
3)Item3
#? 1               ←#?で入力待ちになる。
You entered Item1.

continueコマンド

for文やwhile文などの処理を途中で中断し、処理をループの先頭に戻すコマンドがcontinueです。

書式もbreakコマンドと同じで、いくつ前のループ文の先頭へ戻るかを引数で渡せます。

構文

continue 実行を継続したいループまでの深さ

continueコマンド 例1

以下のようにfor文が3つのネストになっている場合2を指定すると“for a”のループから実行を継続します。

#!/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
bash/01_control_statment.1593302820.txt.gz · 最終更新: 2020/06/28 09:07 by matsui