解説
リンクはあるのにtest -eが偽?-Lと-f・-dで入口と参照先を分けよう
壊れたシンボリックリンクを練習用に作り、存在・ファイル・ディレクトリー・リンクの判定を比較。条件式の引用符と結果の読み方を解説。

ファイル一覧に名前があるのに、存在を調べるtest -eが偽になる。シンボリックリンクという「別の場所を指す入口」では、入口と参照先を分ける必要があるよ。
このページでは、普通のファイル、フォルダー、参照先がないリンクを作って比較する。Bashが使えるLinuxなどのターミナルが必要だよ。Windowsの通常のコマンドプロンプト用の手順ではないので、Bashの環境で試してね。
四つの判定は、見ているものが違う
| 条件 | 今回調べる内容 |
|---|---|
| -e | パスの参照先が存在するか |
| -f | 参照先が通常のファイルか |
| -d | 参照先がディレクトリーか |
| -L | パス自体がシンボリックリンクか |
-e・-f・-dは通常リンクをたどって判定する。一方-Lはリンク自体を見るため、参照先がなくても真になることがあるんだ。
専用の練習場所を作る
次の一まとまりをBashのターミナルで実行する。一時ディレクトリーの中に新しい練習データだけを作るので、元のファイルや設定は変えないよ。
practice_dir=$(mktemp -d)
cd "$practice_dir"
printf 'sample\n' > note.txt
mkdir box
ln -s missing.txt broken
for path in note.txt box broken absent; do
e=0; f=0; d=0; link=0
if [ -e "$path" ]; then e=1; fi
if [ -f "$path" ]; then f=1; fi
if [ -d "$path" ]; then d=1; fi
if [ -L "$path" ]; then link=1; fi
printf '%s e=%s f=%s d=%s L=%s\n' "$path" "$e" "$f" "$d" "$link"
done
ln -sはリンクを作るコマンド。この例では、まだ作っていないmissing.txtを指すbrokenという名前だけを作る。absentは入口も参照先も作らない比較用の名前だよ。
表示の1と0を読もう
note.txt e=1 f=1 d=0 L=0
box e=1 f=0 d=1 L=0
broken e=0 f=0 d=0 L=1
absent e=0 f=0 d=0 L=0
ここで表示する1は条件が真、0は偽という練習用の値。シェルの終了コードそのものではないよ。終了コードでは成功が0になるので、混同しないようにしよう。
brokenは-eが0でも-Lが1。入口自体はあるが参照先がない、という違いを読み取れる。単に「-eが偽ならその名前は完全に存在しない」と扱わないでね。
引用符と操作の順序にも気を付ける
例ではパスを"$path"と二重引用符で囲んでいる。空白が含まれる名前でも一つの引数として渡すためだよ。条件式の[と]の前後にも区切りの空白が必要になる。
存在確認に成功しても、その後の読み取りや変更が成功する保証にはならない。権限不足があったり、確認後に別の処理で状態が変わったりすることもある。実際に開く操作の失敗も別に処理しよう。今回の例は、同時変更のない自分の練習場所に限っているよ。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。