Bashのtestコマンドでファイル比較する方法:基本構文と実践例

Published on: | Last updated:

最近、ちょっとしたシェルスクリプトを書いてて、改めて思ったことがあるんだよね。地味だけど、すごく大事なこと。

そう、ファイルの存在チェック。知ってる?Bashのtestコマンド、もしくは[ ]のやつ。これ、適当にやってると、後でスクリプトが変なエラー吐いて止まったりする。正直、面倒くさがらずに最初にちゃんとやっとくのが一番だなって。うん。

で、結論から言うと…

スクリプトの最初にif [ -f "$FILE" ]とかif [ -d "$DIR" ]とかを書いておくだけで、大半の「ファイルないよ!」系エラーは防げる。マジで。これがあるだけで、スクリプトの安定感が全然違うんだ。

なんていうか、料理する前に「材料、ちゃんと全部あるかな?」って確認するみたいな感じ。当たり前だけど、意外と忘れがち。

なんでそんなに大事なの?

まあ、単純な話で。例えば、ログをファイルに書き出すスクリプトがあったとして。

もしログを保存するディレクトリ(例:/var/log/myapp/)がなかったら?いきなり書き込もうとしたら、No such file or directoryって怒られてスクリプトが止まる。それは困るよね。

だから、何かアクションを起こす前に、「そもそも、それ、そこに存在する?」って確認する癖をつけるのが重要。うん。守りの一手って感じかな。

スクリプトが判断に迷う分かれ道
スクリプトが判断に迷う分かれ道

よく使うやつ、どう使い分ける?

似たようなオプションがいくつかあって、最初はちょっと戸惑うかもしれない。個人的には、この3つを覚えておけばだいたい何とかなると思ってる。

オプション 何を確認するか 個人的な使いどころ
-e FILE ファイルでもディレクトリでも、とにかく「何か」が存在するか うーん、あんまり使わないかも。「とにかくそこに何かある?」ってざっくり知りたい時だけかな。良くも悪くも大雑把。
-d FILE それが「ディレクトリ」かどうか これはよく使う。cdする前とか、ファイルを置くためのフォルダがあるか確認する時とか。必須レベル。
-f FILE それが「通常のファイル」かどうか これも鉄板。これから読み書きする対象がちゃんとファイルであることを確認したい時。一番出番が多いかもしれないね。

公式のドキュメント、man testを引けば全部書いてあるんだけど…正直、情報量が多すぎて読むの大変じゃない?笑

だから、まずはこの3つ。特に-d-fを使いこなせるようになるのが近道だと思う。実際、日本のQiitaとか技術ブログでよく見るのも、この2つを使った実践的なパターンが多い気がするしね。結局、みんなが使うのって限られてくるんだよな。

実際のコードで見てみようか

理屈だけだとピンとこないから、いくつか簡単な例を見てみるのが早い。

まず基本、ディレクトリがあるかチェック (-d)

これは、さっきも言ったけど、何かを保存したり、移動したりする前に絶対やるべきやつ。


#!/bin/bash
# check_dir.sh

# 確認したいディレクトリ
TARGET_DIR="/home/user/logs"

if [ -d "$TARGET_DIR" ]; then
  # ディレクトリがあった場合の処理
  echo "✔ $TARGET_DIR は存在します。処理を続行します。"
  # cd "$TARGET_DIR" とか ls -l とか…
else
  # なかった場合の処理
  echo "❌ $TARGET_DIR が見つかりません。作成しますか? (y/n)"
  # mkdir -p "$TARGET_DIR" とか…
fi

これを実行すると、もし/home/user/logsがなければ、ちゃんと「見つかりません」って言ってくれる。いきなりエラーで落ちるより、ずっと親切だよね。個人的には、else側でディレクトリを自動で作っちゃう(mkdir -p)処理を入れることが多いかな。

ターミナルで実際にコードを書いてる感じ
ターミナルで実際にコードを書いてる感じ

次に、ファイルがあるかチェック (-f)

設定ファイルを読み込む、とか、データファイルを処理する、とか。そういう時に使う。

ここでのポイントは、-eじゃなくて-fを使うこと。だって、もし同じ名前の「ディレクトリ」があったら?ファイルを読み込もうとしてエラーになる。だから、「ファイルであること」をちゃんと確認するのが大事。


#!/bin/bash
# check_file.sh

CONFIG_FILE="$HOME/.my_app_config"

echo "設定ファイルを確認します: $CONFIG_FILE"

if [ -f "$CONFIG_FILE" ]; then
  echo "✔ 設定ファイルを読み込みます。"
  # source "$CONFIG_FILE" とか…
else
  echo "❌ 設定ファイルが見つかりません。"
  echo "デフォルト設定で動作します。"
fi

こうしておけば、設定ファイルがなくても、スクリプトは止まらずに「デフォルト設定で動く」っていう代替ルートに進める。こういうのが、安定したスクリプトってことなんだと思う。

じゃあ「-e」はいつ使うの?

正直、僕はあまり使わないんだけど…。あえて言うなら、ファイルかディレクトリか、どっちでもよくて、とにかく「同名の何か」が存在してほしくない時、とかかな。

例えば、新しいファイルかディレクトリを作ろうとしてて、既に何かがあったら上書きしちゃうかもしれないから、先に確認する、みたいな。


#!/bin/bash
# check_exists.sh

TARGET_NAME="new_project"

# -e でファイルかディレクトリか問わず存在をチェック
if [ -e "$TARGET_NAME" ]; then
  echo "❌ '$TARGET_NAME' という名前のファイルかディレクトリが既に存在します。"
  echo "処理を中断します。"
  exit 1
else
  echo "✔ '$TARGET_NAME' は利用可能です。作成処理を開始します。"
  # mkdir "$TARGET_NAME" とか…
fi

こんな感じ。何かを「作る」前の安全確認だね。でも、結局-dとか-fで個別に確認する方が、後々の処理が書きやすいことが多い気はする。うん。

チェックがあるかないかの結果の違い
チェックがあるかないかの結果の違い

よくある間違いとか、気をつけること

最後に、ちょっとだけ細かい話を。これ、僕も昔よくやったミスなんだけど。

変数を使う時は、必ずダブルクォートで囲むこと。if [ -f $FILE ]じゃなくて、if [ -f "$FILE" ]みたいに。

なんでかって言うと、もしファイル名にスペース(空白)が含まれてたら、クォートがないとそこでコマンドが壊れちゃうから。例えば$FILEの中身が "My Documents" だったら、[ -f My Documents ]って解釈されて、エラーになる。

これはもう、おまじないだと思って、常に変数には""をつける癖をつけとくといいよ。うん、絶対。

まあ、そんな感じかな。すごく地味な話だったけど、こういう基礎がしっかりしてると、後々作るものが全然違ってくるから。うん、たぶん。

…で、あなたの場合はどう?シェルスクリプト書く時、どのチェックを一番よく使う?やっぱり -f かな。それとももっとマニアックなやつ?もしよかったら聞かせて。

Related to this topic:

Comments

  1. Guest 2025-07-19 Reply
    へぇ〜、シェルスクリプトのファイル操作って奥が深いですね!海外のエンジニアと話してると、こういうテクニックの違いとか面白いんですけど。実際のプロジェクトでどう活かすかが肝心だと思います。バッチ処理とかで超便利そう!
  2. Guest 2025-07-18 Reply
    最近、Bashスクリプトの勉強始めたんですけど、ファイル操作のテクニックって結構奥が深くて。先輩に教わったチェックコマンドとか、めっちゃ便利だなって。実務で使えそうな気がしてワクワクしてます!
  3. Guest 2025-06-15 Reply
    Bashスクリプトの勉強、めっちゃ大変だったけど、今はだいぶ理解できてきた!特にファイル操作のテクニックとか、めっちゃ役立つよね。実際のプロジェクトで使えそう👍
  4. Guest 2025-06-14 Reply
    へえ、Bashスクリプトでファイル操作って奥が深いですよね!初心者にとって、こういった細かいチェック方法って結構難しく感じるんじゃない?特にテストコマンドの使い方とか、どんな風に実践されてるんでしょうか?
  5. Guest 2025-06-05 Reply
    あの、ちょっと気になることがあるんですけど。このBashスクリプトの検証方法って、初心者には少し難しくない?もう少し具体的な例とか、実践的なサンプルがあると助かるかも。
  6. Guest 2025-05-28 Reply
    へぇ〜、Bashのファイル操作って奥が深いですよね!海外のエンジニアと話してて、こういうスクリプトの小技、めっちゃ勉強になります。実際のプロジェクトで役立つテクニックばかりで、すごく興味深いです!
  7. Guest 2025-04-22 Reply
    この記事の内容は便利そうだけど、実際にはエラー処理や例外ケースについても触れてほしいな。特にファイルが存在しない場合とか、権限の問題なんかでトラブルになりがちだから、その辺もカバーしてくれると嬉しい!