ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

Linux におけるパス末尾のスラッシュとシンボリックリンクの関係

Linux では、ディレクトリを明示的に指定するために、パスの末尾に "/" を付ける方法がよく使われます。本記事では、その理由を詳しく解説します。

末尾のスラッシュの意味

パスの末尾に "/" がある場合、ディレクトリであることを明示する意味を持ちます。以下の man ページの記述が根拠となります。

末尾のスラッシュ
パス名が '/' で終わっている場合、 ステップ 2 において、その前にある構成要素の解決法を次のように強制する: その構成要素が存在しなければならず、ディレクトリとして解決される。 存在しない場合は、末尾の '/' が無視される。 (また同様に、末尾に '/' があるパス名は、 '.' を末尾に加えて得られるパス名と等しい。)

man path_resolution (7): ファイルのパス名の解決方法

つまり、末尾に "/" を付けることで、そのパスがディレクトリであることを明示できます。

シンボリックリンクの扱い

パスがシンボリックリンクを指す場合、リンク自体を扱うのか、リンク先の実体を扱うのかは、システムコールやコマンドの挙動に依存します。

最後がシンボリックリンクのとき
パス名の最後の構成要素がシンボリックリンクである場合、 参照されるファイルをシンボリックリンクとするか、 その内容についてパスを解決した結果とするかは、 システムコールに依存する。

man path_resolution (7): ファイルのパス名の解決方法

以下の実験例を通して、この挙動の違いを確認します。

実験:シンボリックリンクと末尾のスラッシュ

環境設定

Red Hat Enterprise Linux release 9.5 で検証しました。

以下のディレクトリ構成を用意しました。

# ls -l /test_dir/
lrwxrwxrwx. 1 root root  8  32 08:17 link_dir -> real_dir
drwxr-xr-x. 2 root root 22  32 08:17 real_dir

# ls -l /test_dir/real_dir/
-rw-r--r--. 1 root root 0  32 08:17 file.txt

# ls -l /copy_dir/
(ファイル無し)

ls コマンドの挙動

# ls /test_dir/link_dir
file.txt

# ls /test_dir/link_dir/
file.txt

パス末尾の "/" の有無にかかわらず、リンク先のディレクトリの内容が表示されました。

ls -l コマンドの挙動

# ls -l /test_dir/link_dir
lrwxrwxrwx. 1 root root 8  32 08:17 /test_dir/link_dir -> real_dir

# ls -l /test_dir/link_dir/
-rw-r--r--. 1 root root 0  32 08:17 file.txt
  • ls -l /test_dir/link_dir(末尾の "/" なし)
  • ls -l /test_dir/link_dir/(末尾の "/" あり)

cp -r コマンドの挙動

# cp -r /test_dir/link_dir /copy_dir/link_dir_none
# cp -r /test_dir/link_dir/ /copy_dir/link_dir_slash

# ls -l /copy_dir/
lrwxrwxrwx. 1 root root  8  32 08:27 link_dir_none -> real_dir
drwxr-xr-x. 2 root root 22  32 08:28 link_dir_slash

# ls -l /copy_dir/link_dir_slash/
-rw-r--r--. 1 root root 0  32 08:28 file.txt
  • cp -r /test_dir/link_dir /copy_dir/link_dir_none(コピー元の "/" なし)
  • cp -r /test_dir/link_dir/ /copy_dir/link_dir_slash(コピー元の "/" あり)

find コマンドの挙動

find コマンドはパスがシンボリックリンクだった時の挙動を man で明確に説明しています。デフォルトはシンボリックリンクをたどりません。"-L" オプションを加えることで、シンボリックリンクをたどります。

# find /test_dir/link_dir
/test_dir/link_dir

# find /test_dir/link_dir/
/test_dir/link_dir/
/test_dir/link_dir/file.txt

# find -L /test_dir/link_dir
/test_dir/link_dir
/test_dir/link_dir/file.txt

# find -L /test_dir/link_dir/
/test_dir/link_dir/
/test_dir/link_dir/file.txt
  • デフォルトの find ではパス末尾の "/" の有無で挙動が変わります。
    • "/" なしだと、シンボリックリンク自体を結果として出力します。
    • "/" ありだと、リンク先の内容をたどります。
  • "-L" オプションを付けると、パス末尾の "/" の有無に関わらず、リンク先の内容をたどります。

まとめ

  • パスの末尾に "/" を付けることで、そのパスがディレクトリであることを明示できる。
  • パスがシンボリックリンクを指し示す場合、パス末尾の "/" の有無で、コマンドによって挙動が異なる。
  • 一部のコマンド(例:find)では、オプションを使うことでシンボリックリンクの扱いを統一できる。

Linux のパス指定において、末尾に "/" を付けるかどうかは動作上の違いを生む重要な要素です。この仕様を理解して正しく指定すれば、意図通りの結果を得やすくなります。