今回は前回に引き続き、シェルスクリプトを扱います。
制御文は通常のプログラミングと同じく分岐やループのことを指します。
検証と条件式
分岐の制御文に入る前に、シェルスクリプト(Linuxコマンド)特有の検証のやり方について確認しておきます。
シェルスクリプトでは検証を行う際に、「test」コマンドを使用します。
「test」コマンドでは真の場合に「0」を偽の場合に「0以外」を返却します。
test 条件文
また検証は「[]」コマンドをによっても実行することができます。
[ 条件文 ]
よく言われていることですが、「[」と「]」はあくまでコマンドとして扱われるので制御文との間にスペースをいれるのが必須になっています。
if文の制御文の中に組み込んだとき、通常のプログラミング言語と見た目的には似たような形になりますが、あくまでtestコマンドと同等の働きをしているということを念頭に置いておくとエラー発生時などに解決が早くなるのではないかと思います。
以下に主要な条件式を列挙しますが、これをそのまま覚えようとするのはなかなか辛いところでしょう。
■ファイル形式の検証
ファイル形式の検証では指定したファイルが、通常ファイルかディレクトリかなどファイルの形式が一致している場合に真を返します。
条件式 | 検証内容 |
---|---|
|
通常ファイルがあるか |
|
ディレクトリがあるか |
|
読み込み可能なファイルがあるか |
|
書き込み可能なファイルがあるか |
|
実行可能なファイルがあるか |
|
サイズが0より大きいファイルがあるか |
|
シンボリックリンクであるファイルがあるか |
■ファイル特性の検証
「-e」を条件式にした場合、ファイルの形式を問わずファイルでもディレクトリでもいいから存在することを検証することになります。※いまいち使用シーンが思いつかない
「nt」はnew timeでしょうか。
条件式 | 検証内容 |
---|---|
|
ファイル(ディレクトリ含む)があるか |
|
ファイル1がファイル2より新しいか |
|
ファイル1がファイル2より古いか |
■数値の検証
シェルスクリプトでは数値の検証に使う等号、不等号などは一般的な記号ではなくオプションの様な形で指定します。
この辺は今回勉強するまであまり認識していませんでした。
一見分かりにくいですが、イコールの「e」を追っていけばなんとかなりそうな感じ。
条件式 | 検証内容 |
---|---|
|
数値1と数値2が等しいか |
|
数値1が数値2以上(≧)か |
|
数値1が数値2より大きいか |
|
数値1が数値2以下(≦)か |
|
数値1が数値2より小さいか |
|
数値1が数値2が等しくないか |
■文字列の検証
一般的な文字列(String)に対する検証。
条件式 | 検証内容 |
---|---|
|
文字列の長さが0より大きいか |
|
文字列の長さが0であるか |
|
2つの文字列が等しいか |
|
2つの文字列が等しくないか |
■論理演算子
一般的なANDやORなどの表現。
条件式 | 検証内容 |
---|---|
|
条件式が偽であるか |
|
両条件が真であるか |
|
いずれかの条件が真であるか |
おまけ:コマンドラインでの実行
これらの条件式はあくまでコマンドの一つでもあるのでコマンドライン上でも実行することができます。
実践的にはコマンドライン上ではあまり使う機会はない気がしますが。
・shell_test.shのファイルがカレントディレクトリに存在するか
[wantan@localhost lpic2]$ test -f shell_test.sh; echo $? 0
・shell_testXX.shのファイルがカレントディレクトリに存在するか
[wantan@localhost lpic2]$ test -f shell_testXX.sh; echo $? 1
また、「[ ]」を用いることでも同様の結果が得られます。
[wantan@localhost lpic2]$ [ -f shell_test.sh ]; echo $? 0 [wantan@localhost lpic2]$ [ -f shell_testXX.sh ]; echo $? 1
条件分岐
ここからは一般的な分岐やループなどの制御文を扱います。
if文
シェルスクリプトにおける条件分岐は「if」文により実行します。
書式は以下の通りです。
if 条件式 then 真の場合の実行文 else 偽の場合の実行文 fi
・サンプルスクリプト
適当に条件式を当てはめてスクリプトを作成してみます。
#!/bin/bash #引数が入力されているか判定する #先頭行は以下の文と等価 #if test -n "$1" if [ -n "$1" ] then echo "検証結果は真" else echo "検証結果は偽" fi
・実行結果
[wantan@localhost lpic2]$ source if_test.sh 検証結果は偽 [wantan@localhost lpic2]$ source if_test.sh wantan 検証結果は真
不要であればelse部は省略でき、条件を追加したい場合には「elif」文により追加します。
・サンプルスクリプト2
#!/bin/bash if [ -z "$1" ] then echo "入力がないので終了します。" exit fi if [ 'wantan' = $1 ] then echo "ユーザ名" elif [ 'pass' = $1 ] then echo "パスワード" else echo "意味のない入力" fi
case文
シェルスクリプトの条件分岐には「case」文も用意されています。
分岐の条件が多くなる場合にはこちらを使用した方が可読性などの観点から好まれると思われます。
・書式
case 式 in 値1) 実行文;; 値2) 実行文;; esac
値と実行文は任意の個数だけ増やすことができます。
また、「)」や「;;」の記号が個人的に忘れやすい。
・サンプルスクリプト
#!/bin/bash case $1 in 'wantan') echo 'ユーザ名';; 'pass') echo 'パスワード';; 'file') echo 'ファイル名';; esac
・実行例
[wantan@localhost lpic2]$ ./case_test.sh wantan ユーザ名 [wantan@localhost lpic2]$ ./case_test.sh pass パスワード [wantan@localhost lpic2]$ ./case_test.sh TTTTT [wantan@localhost lpic2]$
繰り返しの制御文
for文
多くの言語でも使用される一般的な繰り返しの制御文である「for」文はシェルスクリプトでも共通となります。
・書式
for 変数名 in 任意のリスト do 実行文 done
適当にサンプルを作成してみます。
・サンプルスクリプト
#!/bin/bash #引数を表示していくスクリプト num=0 for param in $@ do num=`expr $num + 1` echo "第$num引数は$param" done
・実行例
[wantan@localhost lpic2]$ ./for_test.sh a bb ccc dddd eeeee 第1引数はa 第2引数はbb 第3引数はccc 第4引数はdddd 第5引数はeeeee
while文
こちらも繰り返し文として一般的なwhile文を使用することができます。
while文では条件式が満たされている間ループ処理を繰り返すことができます。
・書式
while 条件式 do 任意の実行文 done
・サンプルスクリプト
#!/bin/bash num=0 while [ $num -ne 5 ] do num=`expr $num + 1` echo "今は$num番目" done
・実行例
[wantan@localhost lpic2]$ ./while_test.sh 今は1番目 今は2番目 今は3番目 今は4番目 今は5番目
標準入力を受け付ける
readコマンド
ここは他のプログラム言語などでは同等のものをあまり使わない場合もあるかもしれません。
シェルスクリプトではread文を用いることによりシェルスクリプトの実行中に標準入力を受け付けることができます。
ユーザに入力を促す場合など、シェルスクリプトでは実用度も高いところだと思います。
・書式
read 変数
実際に適当なサンプルを作成してみると早いですが、標準入力を変数の中に格納します。
・サンプルスクリプト
#!/bin/bash echo '名前を入力してください' read name touch "$name".txt echo 'あなたのファイルを作成しました'
・実行例
[wantan@localhost lpic2]$ ./read_test.sh 名前を入力してください wantan あなたのファイルを作成しました [wantan@localhost lpic2]$ ll 合計 32 -rwxr-xr-x. 1 wantan group1 140 11月 7 02:00 case_test.sh -rwxr-xr-x. 1 wantan group1 139 11月 7 02:35 for_test.sh -rwxr-xr-x. 1 wantan group1 238 11月 7 01:50 if_test.sh -rwxr-xr-x. 1 wantan group1 136 11月 7 03:13 read_test.sh -rwxr-xr-x. 1 wantan group1 134 11月 3 23:12 shell_test.sh -rwxr-xr-x. 1 wantan group1 68 11月 3 23:22 shell_test2.sh -rw-r--r--. 1 wantan group1 0 11月 4 23:37 test.txt -rw-r--r--. 1 wantan group1 85 11月 7 03:10 testlist.txt -rw-r--r--. 1 wantan group1 0 11月 7 03:17 wantan.txt -rwxr-xr-x. 1 wantan group1 94 11月 7 02:59 while_test.sh [wantan@localhost lpic2]$
またreadコマンドとwhileコマンドを組み合わせることで、ファイルを一行ずつ読み込んでいく処理を実装することもできます。
最後に他のコマンドとも組み合わせてサンプルを作成してみます。
・サンプルスクリプト
読み込むファイルを指定し、一行ずつ読み込みながら処理を実行するスクリプトです。
#!/bin/bash echo 'ファイル名を入力してください' read filename if ! [ -f $filename ] then echo 'ファイルが存在しません、処理を終了します。' exit fi echo "*********ファイルの内容************" num=0 while read param do echo "$num:$param" num=`expr $num + 1` done < $filename
・実行例
[wantan@localhost lpic2]$ ./sample.sh ファイル名を入力してください file.txt ファイルが存在しません、処理を終了します。 [wantan@localhost lpic2]$ ./sample.sh ファイル名を入力してください testlist.txt *********ファイルの内容************ 0:第1引数はa 1:第2引数はbb 2:第3引数はccc 3:第4引数はdddd 4:第5引数はeeeee [wantan@localhost lpic2]$
ーーーーーーーーーーーーーーーーーーーーーーー
今回はここまで。
諸事情につき一旦中断か続きがないかもしれません。
・前回(第三回)
www.wantanblog.com
・次回(第五回)
www.wantanblog.com