12.3 いろいろな構文
Linux Essentials Online Text | 2021/07/29

プログラムの3要素とは

プログラミングの基礎は以下の3要素です。

● 順次実行
● 条件分岐
● 繰り返し

今まで実施してきたのは「順次実行」、つまり上から順番に実行される構文です。

プログラミングでは条件によって挙動を切り替えることが重要になります。それを条件分岐と言います。条件分岐を行うことで、条件によって異なる処理を行い複雑な処理を行うことができます。

また、条件分岐と同じくらい重要な機構が繰り返しです。同じ処理を繰り返し行い「ある条件が成立したときに終了する」という形式が用いられています。

これらは、どのプログラミング言語に存在する機能です。もちろんシェルスクリプトでも存在します。

条件分岐(if 文)

※※条件分岐について※※
条件分岐は、上記の通りプログラミングの3要素の1つです。
Linux Essentials 資格の範囲に含まれませんので覚える必要はありませんが、どのような機能かは知っておくとよいでしょう。一読して、知識として覚えておくことをお勧めします。

条件分岐で、最も代表的なのはif文です。文法は次の通りです。

構文:

if 条件式1 then 実行文①
   else
        実行文②
fi

条件式1の結果が「真」ならば、実行文①を実行します。条件式1の結果が「偽」ならば実行文②を実行します。
もし、さらなる条件がある場合は下記の通りelifを使います。

if 条件式1 then 実行文①
   elif 条件式2 then
	       実行文②
   else
        実行文③
fi

この場合は、 条件式1の結果が「真 」ならば、実行文①を実行します。条件式1の結果が「偽」ならば、条件式2を確認します。 条件式2の結果が 「真 」ならば、実行文②を、「偽」ならば実行分③を実行します。

なお、if文はfiで終了します。この「文をはじめたコマンドの逆さで終了する」という方式は他の文法箇所でも現れます。

条件式

if文で利用される条件式を使用するにあたり、下記のような演算子を使用します。

文字比較演算子比較内容
a = ba とbが等しいければ真
a != ba とbが等しくなければ真
数値比較演算子比較内容
a -eq ba とbが等し(equal)ければ真
a -ne ba とbが等しくなければ(not equal)真
a -ge baがb以上(grater equal)であれば真
a -le baがb以下(less equal)であれば真
a -gt baがbより大きい(grater than)値であれば真
a -lt baがb未満(less than)であれば真
ファイル属性比較演算子比較内容
-f ファイルパスパスが存在し、それがファイルであれば真
-d ディレクトリパスパスが存在し、それがディレクトリであれば真
-e パスパスが存在すれば真
-r ファイルパスファイルが存在し、スクリプトを実行しているユーザに対し、読み取り権限があれば真
-w ファイルパスファイルが存在し、スクリプトを実行しているユーザに対し、書き込み権限があれば真
-x ファイルパスファイルが存在し、スクリプトを実行しているユーザに対し、実行権限があれば真
-L ファイルパスファイルが存在し、シンボリックリンクであれば真

ファイルの属性比較演算子は指定したパスが条件に合っていれば真、合わなければ偽と判断します。そのため、演算子とパスはセットで表記します。具体的には、演算子の後にパスを指定し、指定したパスが演算子に該当するかどうかで条件式とします。

<演習:if文の作成>

if_test.shを作成します。

$ vi if_test.sh

中身は以下のように記載しましょう。

#!/bin/bash

STR1=$1
STR2=$2
if [ $STR1 = $STR2 ] ; then
                echo '両者は等しい文字列です。'
        else
                echo '両者は異なる文字列です。'
        fi

以下のように、実行結果を確認することができます。

$ chmod +x if_test.sh
$ sh if_test.sh test test
両者は等しい文字列です。
$ sh if_test.sh test text
両者は異なる文字列です。

論理積と論理和

条件分岐では、複数の条件を重ねることができます。例えば、条件Aと条件Bが同時に成立している必要があるときは、「条件Aかつ条件Bが成立」ということで論理積(=AND)が用いられます。同じく「条件Aもしくは条件Bが成立」の場合は、論理和(=OR)が用いられます。

シェルスクリプトにおいて、論理積・論理和の書き方はアルファベットと記号の2通りの記載方法があります。これらは、それぞれ[]の内側か外側かで使われ方が変わることに気をつけてください。

<論理積>

論理積は「-a」を用いる場合と、「&&」を用いる場合があります。

書式:

[条件A -a 条件B -a 条件C ] ….
[条件A] && [条件B] && [条件C] ….

<論理和>

論理和を表す記号も2通り存在します。「-o」と「||」です。利用形式は次の通りです。

書式:

[条件A –o 条件B -o 条件C ] ….
[条件A] || [条件B] || [条件C] ….

<実習:論理積を使ったシェルスクリプトの実行>

$ vi if_logisum.sh
#!/bin/bash

NUM1=$1
if [ $NUM1 -gt 5 -a $NUM1 -lt 10 ] ; then
		echo “$1”は5よりも大きく10よりも小さい。
        fi
$ chmod +x if_logisum.sh
$ sh if_logisum.sh 8
“8”は5よりも大きく10よりも小さい。

上記のサンプルは、$NUM1が5未満の時と、10よりも大きい場合の処理が書かれていません。上記のサンプルに追記して、どのような数値でも対応できるようにてみましょう。

#!/bin/bash

NUM1=$1
if [ $NUM1 -gt 5 -a $NUM1 -lt 10 ] ; then
		echo “$1”は5よりも大きく10よりも小さい。
	elif [ $NUM1 -lt 5 ] ; then
		echo “$1”は5と同じか、より小さい。
	else
		echo “$1”は10と同じか、より大きい。
        fi

上記が回答例です。6行目~10行目が追記分です。
elifを使って、最初の条件式に漏れた数値の新たな条件を指定しています。
例では、2つ目の条件式を「5以下」であることを条件としました。1つ目と2つ目の条件式に漏れるのは「10以上」となるので、3つ目は条件式を書かずに指定しています。

2つ目の条件式を「10以上」にしても問題有りません。

繰り返し(for文)

for文の書式は以下のとおりです。

構文:

for 変数 in 値のリスト
do
   実行文
done

「変数を処理」と「値のリスト」を「変数」に代入し、代入された変数を使って「実行文」を実行します。変数は値のリストの分だけ存在するため、値のリストがなくなるまで繰り返し処理して結果を表示します。実際に試してみましょう。

$ for_test.sh

中身は下記のように入力します。

#!/bin/bash

for i in `seq 11 15`
do
  echo $i
done

for文は「done」までが構文です。
forの右側にある「i」が変数、「`seq 11 15`」が値のリスト、「echo $i」が実行文です。

変数「i」は「i」以外の文字でも問題ありませんが、実行文である「echo $i」に関係するのでこちらの文字も併せて変更する必要があります。

「`seq 11 15`」は、バッククォートで括られていますので、コマンドの実行結果がリストです。seqコマンドは指定した数値を順番に表示するコマンドで、記載のコマンドを実行した場合は「11」から「15」までの数字が順番に表示されるようになります。つまり、値のリストは「11、12、13、14、15」です。

つまり、このスクリプトを実行すると変数「i」に対して値のリストである「11、12、13、14、15」を「i=11」「i=12」「i=13」「i=14」「i=15」として、次々に代入して「echo $i」の処理が行われます。つまり、「11」から「15」までが順番に出力されます。

なお、コマンドなどの実行結果としてリストを使うこともできます。

この実行例では、lsの実行結果を変数「i」に代入しています。つまり、lsコマンドで表示されるファイルやディレクトリを1つづつ変数「i」に代入することでループ処理が実行されます。

#!/bin/bash

for i in `ls`
do
   echo $i
done
PAGE TOP