MAGAZINE

キャリテク!マガジン

コラム

転ばぬ先のバックアップ (2) testコマンドとbashの条件分岐 補足解説

こんにちは。株式会社パイプラインの濱田です。
前回はコマンドラインによるバックアップ取得を取り上げましたが、今回はtestコマンドやbashの制御演算子について補足したいと思います。

testコマンドとは

test([)コマンドとは、ファイルの形式のチェックや値の比較を行うコマンドで、条件式を評価して真偽の値を返します。つまり、条件式に合致していたら真の値(zero)を、条件式に合致していなければ偽の値(not zero)を返します。Linuxではcoreutilsパッケージに含まれています。どのパッケージに含まれているかを確認する方法は以下の通りです。

Ubuntu 20.04.2 LTSの場合
nullpopopo@DESKTOP-6PRJLBI:~$ which test
/usr/bin/test
nullpopopo@DESKTOP-6PRJLBI:~$ dpkg --search /usr/bin/test
coreutils: /usr/bin/test
CentOS 7.9の場合
[nullpopopo@marina ~]$ which test
/usr/bin/test
[nullpopopo@marina ~]$ rpm -qf /usr/bin/test
coreutils-8.22-24.el7_9.2.x86_64

例) /etc/hostsファイルが存在していたら「OK」を表示させる

もし /etc/hosts ファイルが存在していたらOKを表示させる例は以下になります。

nullpopopo@DESKTOP-6PRJLBI:~$ [ -f /etc/hosts ] && echo OK
OK

[  ] の中を日本語に訳すると、「/etc/hosts が通常ファイルとして存在するか?」となり、条件式は「-f」になります。この条件式に合致したら、つまり条件式の結果が真(zero値)であれば次のコマンドを実行しなさいという制御演算子が「&&」になります。開きカッコと閉じカッコ、演算子の前後にスペースをあけることに気をつけてください。

testコマンドで使える演算子は多数ありますが、ファイルやディレクトリの検索では以下の演算子がよく使われますので、覚えておくとよいでしょう。以下例では、ファイルもディレクトリも”ファイル”として表現しています。

条件判定例の解説期待する出力結果
-fファイルが通常ファイルであれば真[ -f /etc/hosts ] && echo OK/etc/hosts というファイルが通常ファイルであればOKと出力させるOK
-dファイルがディレクトリであれば真[ -d /etc/hosts ] && echo OK/etc/hosts というファイルがディレクトリであればOKと出力させる何も表示されない
-xファイルが実行可能であれば真[ -x /usr/bin/systemctl ] && echo OK/usr/bin/systemctl というファイルが実行可能であればOKと出力させるOK

例) 数値の比較をtestコマンドで行う

testコマンドの条件式は数値の比較もできます。例えば0と0が等しいならOKを表示しなさい、というコマンドを実行してみましょう。

nullpopopo@DESKTOP-6PRJLBI:~$ [ 0 = 0 ] && echo OK
OK

0と1が等しいならOKを表示しなさい、というコマンドを実行すると、当然何も表示されません。

nullpopopo@DESKTOP-6PRJLBI:~$ [ 0 = 1 ] && echo OK

bashの制御演算子を使いこなそう

前章でも取り上げましたが、前のコマンドが正常終了した(真の値を返した)ら次のコマンドを実行したい場合、「&&(AND制御演算子)」を使います。前のコマンドが異常終了した(偽の値を返した)ら次のコマンドを実行したい場合は「||(OR制御演算子)」を使います。これら演算子はコマンドセパレーターの一種ですが、いろいろあってよくわからない、という方のためにコマンドセパレーターの一覧を作ってみました。例示しているコマンドは1行で実行しています。

コマンドセパレーター意味例の解説期待する出力結果
;コマンド1の後にコマンド2を実行する。コマンド1の実行成否(真偽値)は問わない。ls /etc/Aoh ; ls /etc/resolv.conf/etc/Aoh ファイルをlsコマンドで表示し、その後 /etc/resolv.conf ファイルをlsコマンドで表示する。ls: cannot access '/etc/Aoh': No such file or directory /etc/resolv.conf
&&コマンド1が正常終了した(真の値を返した)らコマンド2を実行する。ls /etc/Aoh && ls /etc/resolv.conf/etc/Aoh ファイルをlsコマンドで表示し、lsコマンドが正常終了した(/etc/Aohファイルがあった)ら、  /etc/resolv.conf ファイルをlsコマンドで表示する。ls: cannot access '/etc/Aoh': No such file or directory
||コマンド1が異常終了した(偽の値を返した)らコマンド2を実行する。ls /etc/Aoh || ls /etc/resolv.conf/etc/Aoh ファイルをlsコマンドで表示し、lsコマンドが異常終了した(/etc/Aohファイルがなかった)ら、  /etc/resolv.conf ファイルをlsコマンドで表示する。ls: cannot access '/etc/Aoh': No such file or directory /etc/resolv.conf

また、AND制御演算子とOR制御演算子は組み合わせて使用することもできます。あまり複雑な条件分岐はきちんとネストしたif文で書いたほうがよいですが、「コマンド1が正常終了したらコマンド2を、コマンド1が異常終了したらコマンド3を実行する」というようなシンプルな使い方であれば、カジュアルに使用してもよいでしょう。

前回は以下のコマンドを例示しました。例示しているコマンドは1行で実行しています。

[ -f /etc/hosts.ORIG ] && sudo cp -p /etc/hosts{,.$(date +%Y-%m-%d)} || sudo cp -p /etc/hosts{,.ORIG}

もし /etc/hosts.ORIG ファイルが通常ファイルとして存在していたら、 /etc/hosts を /etc/hosts.日付 のファイルにコピーし、そうでなければ /etc/hosts を /etc/hosts.ORIG としてコピーしなさい、という意味のコマンドになります。上記コマンド中で使用している「{,}」をブレース展開と呼び、「$()」をコマンド置換と呼びますが、スペースの都合上またの機会に解説したいと思います。

次回は、複数のファイルを圧縮して保存するコマンドについて取り上げます。

まずはエンジニアデビューしたい、という方は、3ヶ月間学びながらお給料が貰える KCCSキャリアテック キャリテク!の門を叩いてみてはいかがでしょう。
https://www.kcct.co.jp/careetec/

関連記事

facebook シェアシェア
LINE シェアシェア