例を示してBashファイルテスト演算子を学ぶ方法

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文を使用できます。

# テストしたいファイルを表します。
# テストする対象ファイルの名前でfile_nameを置き換えます。
FILE="file_name"
# 演算子 - 使用するファイルテスト演算子。
if [ Operator $FILE ]

then
 # 演算子がtrueを返した場合に実行するタスク。
 do something

else
 # 演算子がfalseを返した場合に実行するタスク。
 do something

fi

ファイルの存在を確認します

テストオペレーターの動作の一端を見てきましたが、それだけではそれらの使用方法の詳細を理解するには不十分です。そこで、ファイルの存在を確認するなど、基本的な例から始めましょう。

実際の世界では、設定ファイルが存在するかどうかを確認したい場合がありますが、その前にファイルを作成する前に存在を確認したいですよね。同じファイルが既に存在することがわかったら、ゼロから設定ファイルを構築する時間を無駄にしたくありません。

ファイルがすでに存在するかどうかを確認するには:

1. ターミナルを開き、次のtouchコマンドを実行して新しい test.txt ファイルを作成します。このコマンドは出力を提供しませんが、次のステップでファイルを確認します。

touch test.txt

2. 次に、以下のlsコマンドを実行して、作業ディレクトリ内の新しく作成されたファイル(test.txt)をリストします。

ls -al test.txt

以下の出力は、test.txtファイルを正常に作成したことを確認します。

これでテストファイルがあるので、次の手順でBashスクリプト内でファイルの存在を確認するためのボイラープレートコードブロックを使用できます。

Listing the newly-created file

3. 以下のコマンドを実行して(touch)、「if_file_exists.sh」という新しいシェルスクリプトファイルを作成し、お好みのテキストエディタ(nano)で開きます。

touch if_file_exists.sh && nano if_file_exists.sh

4. これで、以下のコードを新しいif_file_exists.sh ファイルに挿入し、ファイルを保存してエディターを閉じます。

  • 指定されたファイルが存在するかどうかをテストするif-else文を実行します。
  • オペレータがtrueを返すと、ファイルが存在するというメッセージが表示されます。
  • オペレータがtrueを返すと、ファイルが存在しないというメッセージが表示されます。ただし、この場合は自動的にファイルが作成され、FILE変数で定義した名前が付けられます。

ファイルの先頭にある#!/bin/bash行はシェバンとして知られています。シェバンはスクリプトを実行するためにどのインタプリタを使用するかをシステムに伝えます。この場合はBashです。シェバンを含めないと、システムはデフォルトのインタプリタを使用しますが、それがBashであるとは限りません。シェバンがないと、スクリプトが失敗する可能性があります。

#!/bin/bash
# FILE - テストしたいファイルの値を保持する変数。
# 同じコードブロックを使用して異なるファイルをテストできます 
  # $FILE変数の値を変更することで。
FILE="test.txt"

# -eオペレータはファイルの存在をテストします
if [ -e $FILE ]
then
  # オペレータがtrueを返す場合は、ファイルが存在するというメッセージを出力します。
  echo "$FILE exists"
else
  # オペレータがtrueを返す場合は、ファイルが存在しないというメッセージを出力し、
    # その後、FILE変数で定義した名前でファイルが作成されます。
  echo "$FILE does not exist, creating new file" && touch test.txt
fi

5. 以下のコマンドを実行して、新しいスクリプト(if_file_exists.sh)を実行します。

bash if_file_exists.sh

すべてがうまくいくと、ターミナルにtest.txtが存在するメッセージが表示されます。

test.txt exists

6. 次に、以下のコマンドを実行して、テストファイル(test.txt)を削除(rm -rf)し、作業ディレクトリ内のすべてのファイルをリストします。

rm -rf test.txt
ls test.txt

以下では、test.txtがもはやリストされていないことを確認できます。

Deleting the test file

7. 以下のコマンドを再度実行して、if_file_exists.shスクリプトを実行します。

そのため、test.txtファイルはもはや存在せず、-e演算子がfalseを返すときにスクリプトは新しいtest.txtファイルを作成します。

bash if_file_exists.sh
Rerun your if_file_exists.sh script

8. 最後に、以下のlsコマンドを実行して、作業ディレクトリ内のtest.txtファイルをリストします。

ls -al test.txt

以下の出力は、スクリプトが新しいtest.txtファイルを作成したことを確認しています。

Listing the new test.txt file

ファイルが通常のファイルか特殊なファイルかをチェックする

ファイルを開く前や処理する前に、そのファイルが通常のファイルか特殊なファイルかを最初にチェックしたい場合があります。なぜなら、特殊なファイルはファイルシステムに保存されているファイルの一種であり、これらのファイルをいじることがないように注意する必要があるからです。

例えば、特殊なファイルを開こうとするときによくあるエラーは、「ファイルまたはディレクトリがありません」というエラーです。このエラーは、開こうとしているファイルが存在しない場合に発生します。しかし、同じエラーは、通常のファイルの代わりに特殊なファイルを開こうとするときにも発生する可能性があります。

新しいspecial_file.shファイルをテキストエディタで開き、以下のコードを追加して変更を保存します。

以下のコードは前のものと似ています。ただし、このコードでは-e演算子の代わりに-f演算子を使用しています。

#!/bin/bash
# /dev/vmmonファイルは特殊なファイルです
  # Linuxでハードウェアデバイスとの通信に使用されます。
FILE="/dev/vmmon"

# ファイルが
if [ -f $FILE ]
then
  # 演算子がtrueを返す場合、ファイルは通常のファイルであることを示すメッセージが表示されます。
    # ファイルが
  echo "$FILE is a regular file"

else
  # 演算子がtrueを返す場合、ファイルが存在しないか通常のファイルであることを示すメッセージが表示されます。
    #
  echo "Either $FILE does not exist or is not a regular file"

fi

次に、以下のコマンドを実行してspecial_file.shスクリプトを実行します。

bash special_file.sh

変数FILEで指定されたファイル(/dev/vmmon)が特殊なファイルであるため、以下のメッセージが表示されます。

Checking if a file is a regular file

ディレクトリの存在を確認する

これまで、ファイルの存在を確認する方法を学びました。しかし、同じ方法がディレクトリにも適用されるのでしょうか?はい、-dテスト演算子を使用することで可能です。この演算子は、ディレクトリの存在に基づいてアクションを実行する場合に便利です。

たとえば、あるディレクトリから別のディレクトリにすべてのファイルをコピーしたい場合、対象のディレクトリが存在しない場合にはファイルをコピーする前にディレクトリを作成することができます。

1. 以下のlsコマンドを実行して、作業ディレクトリからexample-dirをリストアップしてください。

ls -la example-dir

ディレクトリが存在しないため、「No such file or directory」というメッセージが表示されます。ディレクトリが存在しない場合にフローを中断したくない場合は、次のステップに進んでください。

Listing the example-dir from the working directory

2. 次に、新しいファイルif_dir_exists.shをテキストエディタで開き、以下のコードを追加してファイルを保存します。次のコードは、指定されたディレクトリが存在するかどうかをテストし、-d演算子の返り値に応じてタスクを実行します。

同じ結果を得るには、ifとelseステートメントを逆に切り替えて否定演算子(!)を使用することもできます。実際の状況では、!演算子はよりクリーンで簡潔なスクリプトの作成に役立ちます。

#!/bin/bash
# dir変数にディレクトリ名を定義
dir=example_dir

# ディレクトリ(dir)が存在するかどうかをテスト
if [ ! -d $dir ]
then
  # 演算子がtrueを返す場合、dir変数の値に対してディレクトリを作成
  mkdir $dir
  # test.txtファイルを新しく作成されたディレクトリにコピー
  cp test.txt $dir
  # 上記のタスクに関するメッセージを表示
  echo "The directory has been created, and the test.txt file has been copied."
else
  # 演算子がfalseを返す場合、
    # echoコマンドがディレクトリが存在するというメッセージを表示
  echo "Directory $dir exists"
fi

3. 今、以下のコマンドを実行してスクリプト(if_dir_exists.sh)を実行してください

bash if_dir_exists.sh

メッセージを見ることができます。ディレクトリが作成され、test.txtファイルがコピーされましたexample_dir が存在しないため。

Executing the if_dir_exists.sh to test if a directory exists

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

ls -la example_dir
Confirming the example_dir directory exists and contains the test.txt file

ファイルが空かどうかを確認する

最も使用される3つのファイルテスト演算子(-e, -f, および -d)の使用方法をすでに知っています。しかし、まだ他の演算子も見てみたいと思うでしょう。

通常、ファイルの内容を強調表示して別のファイルにコピーする代わりに、コマンドを実行して作業を行います。ただし、ターゲットファイルが空でない場合がありますので、くれぐれもご注意ください。

なぜ-s演算子を使用してファイルが存在し、空でないかを確認しないのですか?この演算子は、ファイルが存在し、サイズがゼロより大きい場合にtrueを返します。

1. テキストエディタでempty_file.shという名前の新しいファイルを開き、以下のコードを追加してファイルを保存します。

次のコードは、指定されたファイルが空かどうかをテストし、-s演算子が返す値に応じてメッセージを表示します。

#!/bin/bash
#ターゲットファイルの名前を定義します
FILE=test.txt

#-s演算子は、ターゲットファイルが存在し、空でないかどうかをテストします
if [ -s $FILE ]
then
  #演算子がtrueを返す場合、echoコマンドはメッセージを出力します
    #ファイルが存在し、空でないことを示すメッセージを出力します。
  echo "$FILE exists and is not empty"
else
  #演算子がfalseを返す場合、echoコマンドはメッセージを出力します
    #ファイルが存在しないか空であることを示すメッセージを出力します。
  echo "$FILE either does not exist or is empty"
  #ターゲットファイルにテキストを追加します
  echo "This is a test. This is not an empty file" > $FILE
fi

2. 以下のコマンドを実行してスクリプト(empty_file.sh)を実行します。

bash empty_file.sh

下記には、test.txtが存在しないか空であることを示すメッセージが表示されます。しかし同時に、スクリプトはtest.txtファイルにテキストを追加します。

Executing the empty_file.sh file to test if the text.txt file is empty

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

cat test.text
Verifying the text.txt file’s content

4. 最後に、以下のbashコマンドを再度実行してempty_file.shスクリプトを実行します。

bash empty_file.sh

下記には、出力が変更され、test.txtファイルが今やいくつかのテキストを含み、サイズがゼロ(0)より大きいため、test.txtが存在し、空でないことが示されます。

Rerunning the empty_file.sh script to check if the test.txt file is empty

ファイルが存在し、読み込み可能かどうかを確認する

おそらく、あなたの自動化にはファイルを読み込んでタスクを実行する必要があります。そのタスクの成功は、ファイルが読み込み可能かどうかにかかっています。ファイルが存在し、読み込み可能であるかどうかを確認するスクリプトを作成することは、解決策として役立ちます。

ファイルが存在し、読み取り可能かどうかを確認するデモンストレーション:

1. 別のユーザーアカウント(ata)にログインするには、次のコマンドを実行してください。

su - ata

プロンプトは変更され、別のユーザーとしてログインしていることを示します($)。

Logging in to another user account

あるいは、chmodコマンドを使用してファイルのパーミッションを読み取り可能、書き込み可能、またはその両方に変更できます。

2. ログインしたら、テキストエディタでreadable_file.shという新しいファイルを作成してください。

以下のコードをreadable_file.shファイルに追加し、変更を保存します。このコードは、/rootディレクトリにあるtest.txtという名前のファイルが存在し、読み取り可能かどうかを確認します。

#!/bin/bash
# ターゲットファイルを定義する
FILE=test.txt

# ターゲットファイルが読み取り可能かどうかをテストする
# -rを-wに変更して、ファイルが書き込み可能かどうかをテストできます。
if [ -r $FILE ] 
then  
  # オペレーターがtrueを返した場合、ファイルが存在し、読み取り可能であるとメッセージを表示します。
    # オペレーターがfalseを返した場合、ファイルが存在しないか読み取り不可能であるとメッセージを表示します。
  echo "$FILE exists and is readable" 
else  
  # 以下のコマンドを実行して、readable_file.shスクリプトを実行します。
    
  echo "$FILE does not exist or is unreadable"
fi

bash readable_file.sh

このとき、「/root/test.txt」が存在しないか読み取り不可能であるというメッセージが表示されます。 text.test ファイルは /root ディレクトリにあり、現在のユーザー(ata)は text.txt ファイルを読む権限がありません。

Executing the readable_file.sh script

4. 最後に、以下のコマンドを実行して次の操作を行います:

  • sudoers ファイルを変更して、現在のユーザー(ata)が sudo を使用して昇格コマンドを実行できるようにします。
  • readable_file.sh スクリプトを実行して、特定のファイルが読み取り可能かどうかをテストします。
sudo bash
bash readable_file.sh

以下のように出力されますが、これは ata ユーザーが現在 test.txt ファイルを読む許可を持っているため、test.txt が存在して読み取り可能であることが分かります。

Changing the sudoers file and executing the readable_file.sh script

結論

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 ファイルテスト演算子を使用する他の方法も多くあります。

なぜファイルの拡張子をチェックしてみないですか?または、複数のファイルが存在するかどうかを確認して、必要なすべてのファイルが利用可能かどうかを確認してみてください。

Source:
https://adamtheautomator.com/bash-file-test/