本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、条件が成立したときコマンドを実行する「if」コマンドです。
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は条件が成立したときコマンドを実行する「if」コマンドです。
「if」は、何らかの条件を指定して、その条件が真の時のみ処理を行うコマンドです。条件は「指定したコマンドの実行結果が真かどうか」で判定します。この判定には一般にtestコマンド(連載第221回、第222回)を使います。
ifコマンドはbashの内部コマンドです。主にシェルスクリプト内で使用します。ifコマンドを使った一連の処理のことを「if文」と呼ぶことがあります。
以下ではコマンドラインで使用する方法を紹介します。シェルスクリプトを書くに当たり、判定結果を確かめておきたい場合などに役立ちます。
if コマンド; then コマンド; fi
if [ 式 ]; then コマンド; fi
※条件が真の場合と偽の場合で実行するコマンドを変えたい場合は「else」を用いて以下のように記述する。シェルスクリプト内では「;」の位置で適宜改行すると読みやすくなる。
if [ 式 ]; then 真の時実行するコマンド; else 偽の時実行するコマンド; fi
ifコマンドにはオプションはありません。
ある条件が成立したときに、コマンドを実行するには「if 条件; then コマンド; fi」とします。
例えば「指定したテキストファイルに特定の文字列が含まれていたら編集する」という処理を考えてみましょう。ifコマンドを使わずに処理するなら、まずgrepコマンド(第9回)などを用いて文字列の有無を確認し、実行結果を見て編集するかどうかを決めるでしょう。
この一連の処理をifコマンドで書くと「if grep -q 文字列 ファイル; then vi ファイル; fi」のようになります。grepコマンドの「-q」オプションは、実行結果を画面に表示しないというオプションです。viはテキストエディタです(Linux再入門第18回以降)。
画面1では、実行イメージを見るために、viコマンドの代わりにheadコマンド(第3回)でファイルの冒頭部分を出力しています。
if grep -q 文字列 ファイル; then vi ファイル; fi
(ファイルに指定した文字列が含まれていたらviコマンドを起動する)
if grep -q PS1 /etc/bashrc; then vi /etc/bashrc; fi
(/etc/bashrcにPS1という文字列が含まれていたらviコマンドを起動する)
ifコマンドをforコマンド(第215回)と組み合わせると、複数のファイルを対象とした処理を実行しやすくなります。
例えば複数のファイルに対してgrepコマンドで文字列の有無をチェックして、指定した文字列があった場合のみviコマンドを起動するといった場合です。
読みやすいよう、以下のように適宜改行を入れることもできます。シェルスクリプト内ではこのまま動作します。コマンドラインでは2行目以降から「>」というプロンプトに続いて、コマンドを手入力します。
for f in *; do #カレントディレクトリのファイルに対し if grep -q 文字列 $f; then #指定した文字列が含まれていたら vi $f #viコマンドで編集する fi #(if文の終わり) done #(for文の終わり)
画面2では、「/etc/*」に対して、「PS1」という文字列が含まれているファイルを、viコマンドで編集しようとしています。画面の最後、doneの後で[Enter]キーを押すと、コマンドの実行が始まります。
実際に「/etc/*」を指定した場合、ここにはディレクトリが含まれているため、grepコマンドの「ディレクトリです」というエラーメッセージが画面に表示されてしまいます。
コマンドラインで実行する分には困りませんが、「ディレクトリではない(通常のファイルである)」「編集権限がある」といった条件を指定したい場合は、testコマンド(第221回)と組み合わせます。
複数の条件を指定する場合は、さらに論理演算子も使います。コマンド1とコマンド2の両方の実行結果が真の場合にのみ、真になるように指定するには「&&」を使い、「コマンド1 && コマンド2」と書きます。いずれかが真であれば、真になる場合は「||」を使い「コマンド1 || コマンド2」のようにします。
対象のファイルが通常ファイルであり(testコマンドの-fオプションで確認)、さらに自分に編集権限のあるファイルに限定した(-wオプションで確認)としましょう。その上で、grepコマンドを使って文字列の有無を確認し、viコマンドを起動するのであれば以下のようになります。
for f in /etc/*; do if test -f $f && test -w $f && grep -q PS1 $f; then vi $f; fi; done
画面3では、実行イメージを見るために、通常ファイル(-fオプションで確認)、かつ、閲覧権限のあるファイル(-rオプションで確認)に限定した上で、headコマンドで表示しています(※1)。
※1 testコマンドの代わりに[コマンドを使って記述すると、次のようになる。
for f in /etc/*; do if [ -f $f -a -r $f ] && grep -q PS1 $f; then head $f; fi; done
for f in /etc/*; do if test -f $f && test -r $f && grep -q PS1 $f; then head $f; fi; done
(通常ファイルかつ閲覧権限のあるファイルに対して文字列を検索し、文字列を含むファイルの冒頭部分を出力する)(画面3)
ifコマンドを使わずに、&&演算子で短く記述できる場合があります。例えば「コマンド1が真のとき、コマンド2を実行」としたい場合、ifを使って書くならば「if コマンド1; then コマンド2; fi」となります。
この場合は「コマンド1 && コマンド2」とした方が簡単です。「&&」は論理演算子ですが、コマンド1とコマンド2の両方が真であることを判定するとき、実際にはコマンド1が成功したときのみコマンド2の実行を試みます。このため「コマンド1が成功したらコマンド2を実行」のように活用できるのです。
if test -o noclobber; then echo "SET"; fi
(シェルオプション「noclobber」(リダイレクトでファイルを上書きしない、第207回)が設定されていたら「SET」と表示)
test -o noclobber && echo "SET"
(シェルオプション「noclobber」が設定されていたら「SET」と表示)
なお、応用例として「コマンド1が偽のときにコマンド2を実行」であれば「コマンド1 || コマンド2」のように書きます。「||」は、コマンド1かコマンド2のいずれかが真であることを判定する際、コマンド1が失敗したときのみコマンド2を試みます。コマンド1が成功したら「コマンド1 || コマンド2」は真なので、コマンド2を実行する必要がなく、このような動作になります。
西村 めぐみ(にしむら めぐみ)
PC-9801NからのDOSユーザー。PC-486DX時代にDOS版UNIX-like toolsを経てLinuxへ。1992年より生産管理のパッケージソフトウェアの開発およびサポート業務を担当。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『Accessではじめるデータベース超入門[改訂2版]』『macOSコマンド入門』など。2011年より、地方自治体の在宅就業支援事業にてPC基礎およびMicrosoft Office関連の教材作成およびeラーニング指導を担当。
Copyright © ITmedia, Inc. All Rights Reserved.