やあ!このチュートリアルの前のパート(パート1とパート2)では、入力の受け入れ、算術演算によるデータの処理、出力の生成と表示など、シェルスクリプトの基本についてはすでに説明しました。このパートでは、プログラミング言語のより高度なトピック、つまりプログラムでの意思決定について詳しく説明しますが、今回はbashシェルを使用して行います。始めましょう!
今日のほとんどのプログラミング言語は、設定した条件に基づいて決定を下すことができます。条件は、ブール値(trueまたはfalse)に評価される式です。プログラマーなら誰でも、自分のプログラムに入れた決定と論理に基づいて、自分のプログラムを賢くすることができます。 bashシェルは、ifおよびswitch(case)決定ステートメントをサポートします。
Ifステートメント
Ifは、プログラマーが指定した条件に基づいてプログラムで決定を下せるようにするステートメントです。条件が満たされた場合、プログラムは特定のコード行を実行し、そうでない場合、プログラムはプログラマーが指定した他のタスクを実行します。以下は、bashシェルでサポートされているifステートメントの構文です。
単一の決定:
if <condition>
then
### series of code goes here
fi
二重の決定:
if <condition>
then
### series of code if the condition is satisfied
else
### series of code if the condition is not satisfied
fi
複数のif条件:
if <condition1>
then
### series of code for condition1
elif <condition2>
then
### series of code for condition2
else
### series of code if the condition is not satisfied
fi
単一ブラケット構文
if [ condition ]
then
### series of code goes here
fi
二重括弧構文
if ((condition))
then
### series of code goes here
fi
シングルブラケット構文は、bashシェルでサポートされている最も古い構文です。 Linuxのすべての条件文と一緒に使用されます。一方、二重括弧構文は、プログラマーに馴染みのある構文を提供するために、数値ベースの条件ステートメントに使用されます。すべてのタイプのifステートメントは、タスクを実行するために指定された条件を必要とします。
Linuxの条件文
条件ステートメントは、意思決定制御ステートメントと一緒に使用されます。 bashシェルで使用できる条件ステートメントにはさまざまな種類があり、最も一般的なものは、ファイルベース、文字列ベース、および算術ベースの条件です。
ファイルベースの条件は単項式であり、ファイルのステータスを調べるためによく使用されます。次のリストは、bashシェルで最も一般的に使用されるファイルベースの条件を示しています。
オペレーター | 説明 |
-ファイル | ファイルが存在する場合はtrueを返します |
-bファイル | ファイルが存在し、ブロック特殊ファイルの場合はtrueを返します |
-cファイル | ファイルが存在し、文字特殊ファイルの場合はtrueを返します |
-dファイル | ファイルが存在し、ディレクトリである場合はtrueを返します |
-eファイル | ファイルが存在する場合はtrueを返します |
-rファイル | ファイルが存在し、読み取り可能である場合はtrueを返します |
-sファイル | ファイルが存在し、サイズがゼロより大きい場合はtrueを返します |
-sファイル | ファイルが存在し、サイズがゼロより大きい場合はtrueを返します |
-wファイル | ファイルが存在し、書き込み可能である場合はtrueを返します |
-xファイル | ファイルが存在し、実行可能である場合はtrueを返します |
-Nファイル | ファイルが存在し、最後に読み取られてから変更されている場合はtrueを返します |
bashスクリプトでファイルベースの決定を構築する方法を説明する例を見てみましょう。この例では、ファイルがホームディレクトリに存在するかどうかを判断するスクリプトを作成します。
#!/bin/bash
cd
ls
if [ -e sample.sh ]
then
echo "file exists!"
else
echo "file does not exist"
fi
この例では、cdコマンドを使用して、現在のActive Directoryに関係なく、シェルがホームディレクトリに戻るようにしました。さらに、lsコマンドを使用して、ディレクトリ内のファイルのリストを表示し、ファイルが実際に存在するかどうかを確認します。ご覧のとおり、スクリプトは「ファイルが存在します!」というテキストを出力します。 sample.shがホームディレクトリにあるためです。
Note: The shell compiler is very strict in terms of syntax especially with spaces. There should be a space between if and the open bracket and in between brackets and the condition.
次に、ユーザーがスクリプト名を入力し、指定されたファイルのアクセス許可を決定できるようにすることで、コードをより動的にすることで、スクリプトを改善しましょう。
#!/bin/bash
cd
ls -l
read -p "Enter a file name: " filename
if [ -e $filename ]
then
echo "file exists!"
if [ -r $filename ]
then
status="readable "
fi
if [ -w $filename ]
then
status=$status"writable "
fi
if [ -x $filename ]
then
status=$status"executable"
fi
echo "file permission: "$status
else
echo "file does not exist"
fi
文字列のユーザー入力に基づいて決定を下すことも、bashシェルで可能です。文字列ベースの条件は、結果としてバイナリ式を返します。つまり、指定された条件が満たされた場合はtrueを返し、そうでない場合はfalseを返します。一般的に使用される文字列ベースの条件演算子は次のとおりです。
オペレーター | 説明 |
== | 文字列が等しい場合はtrueを返します |
!= | 文字列が等しくない場合はtrueを返します |
-n | テストする文字列がnullでない場合はtrueを返します |
-z | テストする文字列がnullの場合はtrueを返します |
文字列ベースの条件文を使用してサンプルスクリプトを作成しましょう。このスクリプトを使用すると、ユーザーは2つの文字列を入力し、一方の文字列がnullであるかどうか、両方の文字列が等しいか等しくないかを評価できます。
#!/bin/bash
read -p "First String: " str1
read -p "Second String: " str2
if [ -z "$str1" ]
then
echo "The 1st string is null"
elif [ -z "$str2" ]
then
echo "The 2nd string is null"
else
if [ $str1 == $str2 ]
then
echo "The strings are equal"
else
echo "The strings are not equal"
fi
fi
シェルは、算術ベースの条件を宣言するためのいくつかの方法を提供します。 1つは、古いスタイルの1かっこ構文と一緒に使用できるニーモニックを使用する方法で、もう1つは、二重括弧と一緒に使用できる数学に適した記号を使用する方法です。
以下は、シェルでの算術ベースの条件ステートメントで使用可能なニーモニックのリストです。
オペレーター | 使用法/説明 |
-eq | 等しい |
-ge | 大なり記号 |
-gt | より大きい |
-le | 以下 |
-lt | 未満 |
-ne | 等しくない |
ユーザーから整数を受け取り、整数がゼロ、負、奇数、または偶数のいずれであるかを判別するスクリプトを作成しましょう。
#!/bin/bash
read -p "Enter an integer: " int1
if [ $int1 -eq 0 ]
then
echo "Zero"
elif [ $int1 -lt 0 ]
then
echo "Negative"
else
if [ $((int1%2)) -eq 0 ]
then
echo "Even"
else
echo "Odd"
fi
fi
二重括弧構文の算術演算子:
オペレーター | 使用法/説明 |
== | 等しい |
> = | 大なり記号 |
> | より大きい |
<= | 以下 |
< | 未満 |
!= | 等しくない |
それでは、前のスクリプトを再構築して、二重括弧構文を使用しましょう。
#!/bin/bash
read -p "Enter an integer: " int1
if (( $int1 == 0 ))
then
echo "Zero"
elif (( $int1 < 0 ))
then
echo "Negative"
else
if (( $((int1%2)) == 0 ))
then
echo "Even"
else
echo "Odd"
fi
fi
switchステートメントは、シェルスクリプトの別の種類の条件ステートメントです。これにより、プログラマーは、if条件ステートメントと比較して、より簡単な方法でいくつかの値を変数と比較できます。 switchステートメントの構文は次のとおりです。
casein
<pattern1>)
##series of code for pattern1
;;
<pattern2>)
##series of code for pattern2
;;
<patternN>)
##series of code for patternN
;;
*)
##default statements
esac
パターンは、変数の可能な値です。各パターンは、パターンのブレークステートメントとして機能する二重セミコロンで区切られます。 switchステートメントはesacステートメントで閉じられます。
#!/bin/bash
clear
read -p "Integer1: " int1
read -p "Integer2: " int2
echo "======================"
printf "Menu: \n[a] Addition\n[b]Subtraction\n[c]Multiplication\n[d]Division\n"
echo "======================"
read -p "Your choice: " choice
res=0
case $choice in
a)
res=$((int1+int2))
;;
b)
res=$((int1-int2))
;;
c)
res=$((int1*int2))
;;
d)
res=$((int1/int2))
;;
*)
echo "Invalid input"
esac
echo "The result is: " $res
bashシェルは、プログラマーに多くの便利なツールを提供します。今日のほとんどのプログラミング言語と同様に、シェルスクリプトをよりインタラクティブでスマートにする条件付きの決定を行うこともできます。次のシリーズでは、反復制御構造を取り上げます。 「次回まで。
- http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html
- https://linuxacademy.com/blog/linux/conditions-in-bash-scripting-if-statements/
次のレッスン:繰り返し制御の構造