Bashは非常に柔軟で、さまざまなオプションを提供し、ファイルのテストができます。そして、ファイルをテストする方法をお探しの場合、Bashファイルのテスト演算子が役立ちます。
このチュートリアルでは、さまざまなファイルのテスト演算子と、ファイルが存在するか、読み取り可能か、空であるかなどをテストする方法を学びます。
続けて、Bashファイルのテスト演算子を親しみましょう!
前提条件
このチュートリアルは実践的なデモンストレーションになります。一緒に進める場合は、以下を準備してください:
- A Linux system with Bash installed – This tutorial uses Ubuntu 20.04.
ほとんどのLinuxディストリビューションには、デフォルトでBashがインストールされています。ただし、Windowsを使用している場合は、Windows Subsystem for Linux(WSL)をインストールしてBashシェルを取得できます。
- A user account with sudo privileges to run commands as root – This tutorial uses a root account for simplicity. But using a non-root user with sudo access is always recommended.
- このチュートリアルでは、LinuxシステムへのSSHアクセスがあることを前提としています。
Bashファイルテスト演算子とは?
テスト演算子を使う前に、どのように動作するかを見てみましょう。ファイルテスト演算子を使うと、ファイルが存在するか、読み書き可能かなど、ファイルのさまざまな側面をテストできます。
ファイルテスト演算子を使うと、Bashスクリプトでのエラーを防ぐのに役立ちます。以下のコードは、if文のテンプレートです。if-else文は、よくBashスクリプトで見かける強力なツールです。
コードブロックのthenとelse部分はオプションです。それらを使用せずにif文を使用できます。
ファイルの存在を確認します
テストオペレーターの動作の一端を見てきましたが、それだけではそれらの使用方法の詳細を理解するには不十分です。そこで、ファイルの存在を確認するなど、基本的な例から始めましょう。
実際の世界では、設定ファイルが存在するかどうかを確認したい場合がありますが、その前にファイルを作成する前に存在を確認したいですよね。同じファイルが既に存在することがわかったら、ゼロから設定ファイルを構築する時間を無駄にしたくありません。
ファイルがすでに存在するかどうかを確認するには:
1. ターミナルを開き、次のtouchコマンドを実行して新しい test.txt ファイルを作成します。このコマンドは出力を提供しませんが、次のステップでファイルを確認します。
2. 次に、以下のlsコマンドを実行して、作業ディレクトリ内の新しく作成されたファイル(test.txt)をリストします。
以下の出力は、test.txtファイルを正常に作成したことを確認します。
これでテストファイルがあるので、次の手順でBashスクリプト内でファイルの存在を確認するためのボイラープレートコードブロックを使用できます。

3. 以下のコマンドを実行して(touch)、「if_file_exists.sh」という新しいシェルスクリプトファイルを作成し、お好みのテキストエディタ(nano)で開きます。
4. これで、以下のコードを新しいif_file_exists.sh ファイルに挿入し、ファイルを保存してエディターを閉じます。
- 指定されたファイルが存在するかどうかをテストするif-else文を実行します。
- オペレータがtrueを返すと、ファイルが存在するというメッセージが表示されます。
- オペレータがtrueを返すと、ファイルが存在しないというメッセージが表示されます。ただし、この場合は自動的にファイルが作成され、FILE変数で定義した名前が付けられます。
ファイルの先頭にある#!/bin/bash行はシェバンとして知られています。シェバンはスクリプトを実行するためにどのインタプリタを使用するかをシステムに伝えます。この場合はBashです。シェバンを含めないと、システムはデフォルトのインタプリタを使用しますが、それがBashであるとは限りません。シェバンがないと、スクリプトが失敗する可能性があります。
5. 以下のコマンドを実行して、新しいスクリプト(if_file_exists.sh)を実行します。
すべてがうまくいくと、ターミナルにtest.txtが存在するメッセージが表示されます。

6. 次に、以下のコマンドを実行して、テストファイル(test.txt)を削除(rm -rf)し、作業ディレクトリ内のすべてのファイルをリストします。
以下では、test.txtがもはやリストされていないことを確認できます。

7. 以下のコマンドを再度実行して、if_file_exists.shスクリプトを実行します。
そのため、test.txtファイルはもはや存在せず、-e演算子がfalseを返すときにスクリプトは新しいtest.txtファイルを作成します。

8. 最後に、以下のlsコマンドを実行して、作業ディレクトリ内のtest.txtファイルをリストします。
以下の出力は、スクリプトが新しいtest.txtファイルを作成したことを確認しています。

ファイルが通常のファイルか特殊なファイルかをチェックする
ファイルを開く前や処理する前に、そのファイルが通常のファイルか特殊なファイルかを最初にチェックしたい場合があります。なぜなら、特殊なファイルはファイルシステムに保存されているファイルの一種であり、これらのファイルをいじることがないように注意する必要があるからです。
例えば、特殊なファイルを開こうとするときによくあるエラーは、「ファイルまたはディレクトリがありません」というエラーです。このエラーは、開こうとしているファイルが存在しない場合に発生します。しかし、同じエラーは、通常のファイルの代わりに特殊なファイルを開こうとするときにも発生する可能性があります。
新しいspecial_file.shファイルをテキストエディタで開き、以下のコードを追加して変更を保存します。
以下のコードは前のものと似ています。ただし、このコードでは-e
演算子の代わりに-f
演算子を使用しています。
次に、以下のコマンドを実行してspecial_file.sh
スクリプトを実行します。
変数FILE
で指定されたファイル(/dev/vmmon)が特殊なファイルであるため、以下のメッセージが表示されます。

ディレクトリの存在を確認する
これまで、ファイルの存在を確認する方法を学びました。しかし、同じ方法がディレクトリにも適用されるのでしょうか?はい、-d
テスト演算子を使用することで可能です。この演算子は、ディレクトリの存在に基づいてアクションを実行する場合に便利です。
たとえば、あるディレクトリから別のディレクトリにすべてのファイルをコピーしたい場合、対象のディレクトリが存在しない場合にはファイルをコピーする前にディレクトリを作成することができます。
1. 以下のlsコマンドを実行して、作業ディレクトリからexample-dirをリストアップしてください。
ディレクトリが存在しないため、「No such file or directory」というメッセージが表示されます。ディレクトリが存在しない場合にフローを中断したくない場合は、次のステップに進んでください。

2. 次に、新しいファイルif_dir_exists.shをテキストエディタで開き、以下のコードを追加してファイルを保存します。次のコードは、指定されたディレクトリが存在するかどうかをテストし、-d演算子の返り値に応じてタスクを実行します。
同じ結果を得るには、ifとelseステートメントを逆に切り替えて否定演算子(!)を使用することもできます。実際の状況では、!演算子はよりクリーンで簡潔なスクリプトの作成に役立ちます。
3. 今、以下のコマンドを実行してスクリプト(if_dir_exists.sh)を実行してください
メッセージを見ることができます。ディレクトリが作成され、test.txtファイルがコピーされましたexample_dir が存在しないため。

4. 最後に、example_dir ディレクトリに対してlsコマンドを実行して、ディレクトリが存在し、test.txtファイルが含まれていることを確認します。

ファイルが空かどうかを確認する
最も使用される3つのファイルテスト演算子(-e
, -f
, および -d
)の使用方法をすでに知っています。しかし、まだ他の演算子も見てみたいと思うでしょう。
通常、ファイルの内容を強調表示して別のファイルにコピーする代わりに、コマンドを実行して作業を行います。ただし、ターゲットファイルが空でない場合がありますので、くれぐれもご注意ください。
なぜ-s
演算子を使用してファイルが存在し、空でないかを確認しないのですか?この演算子は、ファイルが存在し、サイズがゼロより大きい場合にtrueを返します。
1. テキストエディタでempty_file.shという名前の新しいファイルを開き、以下のコードを追加してファイルを保存します。
次のコードは、指定されたファイルが空かどうかをテストし、-s演算子が返す値に応じてメッセージを表示します。
2. 以下のコマンドを実行してスクリプト(empty_file.sh)を実行します。
下記には、test.txtが存在しないか空であることを示すメッセージが表示されます。しかし同時に、スクリプトはtest.txtファイルにテキストを追加します。

3. test.txtファイルに追加されたテキストを確認するために、以下のcatコマンドを実行します。

4. 最後に、以下のbashコマンドを再度実行してempty_file.shスクリプトを実行します。
下記には、出力が変更され、test.txtファイルが今やいくつかのテキストを含み、サイズがゼロ(0)より大きいため、test.txtが存在し、空でないことが示されます。

ファイルが存在し、読み込み可能かどうかを確認する
おそらく、あなたの自動化にはファイルを読み込んでタスクを実行する必要があります。そのタスクの成功は、ファイルが読み込み可能かどうかにかかっています。ファイルが存在し、読み込み可能であるかどうかを確認するスクリプトを作成することは、解決策として役立ちます。
ファイルが存在し、読み取り可能かどうかを確認するデモンストレーション:
1. 別のユーザーアカウント(ata)にログインするには、次のコマンドを実行してください。
プロンプトは変更され、別のユーザーとしてログインしていることを示します($)。

あるいは、chmodコマンドを使用してファイルのパーミッションを読み取り可能、書き込み可能、またはその両方に変更できます。
2. ログインしたら、テキストエディタでreadable_file.shという新しいファイルを作成してください。
以下のコードをreadable_file.shファイルに追加し、変更を保存します。このコードは、/rootディレクトリにあるtest.txtという名前のファイルが存在し、読み取り可能かどうかを確認します。
このとき、「/root/test.txt」が存在しないか読み取り不可能であるというメッセージが表示されます。 text.test ファイルは /root ディレクトリにあり、現在のユーザー(ata)は text.txt ファイルを読む権限がありません。

4. 最後に、以下のコマンドを実行して次の操作を行います:
- sudoers ファイルを変更して、現在のユーザー(ata)が
sudo
を使用して昇格コマンドを実行できるようにします。
- readable_file.sh スクリプトを実行して、特定のファイルが読み取り可能かどうかをテストします。
以下のように出力されますが、これは ata ユーザーが現在 test.txt ファイルを読む許可を持っているため、test.txt が存在して読み取り可能であることが分かります。

結論
A testing phase is always a priority before making drastic changes, whether on files or directories on your system. And in this tutorial, you’ve learned about the Bash file test operators and how to use them to test if a file (regular or special) or directory exists or if a file is readable or not.
これらの新しいスキルを身につけることで、テストの結果に基づいてどのアクションを取るかを自信を持って決定できます。ただし、Bash ファイルテスト演算子を使用する他の方法も多くあります。
なぜファイルの拡張子をチェックしてみないですか?または、複数のファイルが存在するかどうかを確認して、必要なすべてのファイルが利用可能かどうかを確認してみてください。