web-dev-qa-db-ja.com

「/」に「..」が含まれるのはなぜですか?

/の上にディレクトリはないので、その中の..のポイントは何ですか?

24
EmmaV

ルートディレクトリの..エントリは特殊なケースです。

POSIX標準から( 4.13パス名解決 、ここで.および..エントリはそれぞれ「ドット」および「ドット-ドット」と呼ばれます):

特別なファイル名ドットは、その前任者によって指定されたディレクトリを参照するものとします。特別なファイル名のドットドットは、その前のディレクトリの親ディレクトリを参照します。 特殊なケースとして、ルートディレクトリでは、ドットドットがルートディレクトリ自体を参照する場合があります

根拠にはこれを追加する必要があります( A.4.13パス名解決

ルートディレクトリに対してファイル名のドットドットが参照するものは、実装によって定義されます。バージョン7では、ルートディレクトリ自体を参照します。これは、POSIX.1-2017で言及されている動作です。一部のネットワークシステムでは、構造/../hostname/は別のホストのルートディレクトリを参照するために使用され、POSIX.1ではこの動作が許可されています。

他のネットワークシステムでは、同じ目的で//hostnameを使用しています。つまり、二重の頭文字<slash>が使用されます。 [...]

つまり、要するに、POSIX標準では、すべてのディレクトリに...の両方のエントリが必要であり、../ディレクトリエントリが/ディレクトリ自体(引用された最初のテキストでWordが「かもしれない」ことに注意してください)、しかし、それは実装がそれが他の何かを参照できるようにすることもできます。

ファイルシステムの最も一般的な実装は、/../に解決します。

32
Kusalananda

Kusalananda は、これがPOSIX標準で指定されている動作であることをすでに述べています。しかし、 NIXの歴史 は1970年代初頭に本格的に始まりました。 [〜#〜] posix [〜#〜] は、1980年代の後半、完全な10年半後の日付まで遡ります。実際には、POSIXは、実装によってすでに行われていることを単に指定しただけです。

むしろ、UNIXは早い段階で、さまざまなデバイス上のファイルシステムを単一の統合ディレクトリ階層にマウントすることをサポートしていました。実際には、各ファイルシステムには独自のルートディレクトリがあります。 _/_にマウントされたファイルシステムは、特に特別なものではありません。 (そのcontentsはそうかもしれませんが、ファイルシステム自体はそうではありません。)

sysmountおよびsysumountシステムコールは、UNIX V1で1970〜1971年に導入されたようです(V1は1971〜11年の日付で、 nix HeritageのUnixツリーによると、社会 )。それらは 1.s (それぞれシステムコール番号21および22)で定義され、 7.s で実装されます。 (PDP7 UNIX、日付は1970-01、 -の明白な祖先はないようです )。

おそらくこれがどこに行くのかわかるでしょう:anyファイルシステムを階層のanyの場所にマウントして、特別な場合、各ファイルシステムのルートディレクトリを含む各ディレクトリには、独自の親ディレクトリを指すエントリが含まれている必要があります。ディスク上では、ファイルシステムのルートディレクトリの「上」に他に何もないため、ファイルシステムのルートディレクトリの親ディレクトリエントリを指す論理的な場所は、ファイルシステムのルートディレクトリです。ルートディレクトリの「上」に何かがあるという概念は、そのファイルシステムが階層のルート以外の場所にマウントされている場合にのみ機能します。

マウント中、ルートディレクトリのメモリコピーの「親ディレクトリ」ポインタを書き換えて、マウントポイントディレクトリの親ディレクトリを指すようにすることができます。マウントポイントディレクトリの親ディレクトリがない(つまり、ファイルシステムが_/_としてマウントされている)場合は、そのデータをそのままにしておきます(とにかくそれを指すのに意味のある場所が他にないためです) )または後で個別に処理します(おそらく、Kusalanandaの回答で述べられている_/../hostname/path_および_//hostname/path_の場合と同様です)。

結果の動作は、_/_以外のディレクトリでは、特定のファイルシステムのルートディレクトリであるか、(入れ子の任意のレベルの)サブディレクトリであるかに関係なく、_.._はそのディレクトリの親ディレクトリを指します。 _/_では、_.._は_/_を指します。前者は自然に感じられるものです(_.._は常に同じように機能し、ルートディレクトリに向かって1ステップ移動します)。一方、後者はわずかに特異ですが、少なくとも明らかに何も壊しません(少しですharmルートディレクトリ自体よりもルートディレクトリに移動することができないという点で)。たとえば、任意の数の_../_を叩いて、それらのが少なくともエラーを発生させないことを確認できますある時点で_.._が発生しないため存在します。

17
a CVn

_/_、_/_自体の上にisディレクトリがあります。ルートディレクトリの親ディレクトリはそれ自体です。ルートディレクトリ内の_cd .._または_cd ../.._を使用しても、同じ場所にとどまることができ、エラーは発生しません。

一部のファイルシステムでは、_._も_.._も実際のディレクトリエントリとして存在しない場合があり、OSの仮想ファイルシステムレイヤーによって単にエミュレートされる場合があることに注意してください。


_/../hostname_のようなパスは、 [〜#〜] munix [〜#〜] のような初期のpre-vfsおよびpre-nfsシステムで別のホストのルートにアクセスできるようになっているはずです( "Newcastle Connection" を使用)しかし、そのようなシステムがまだ使用されていることは知りません。また、ソースコードがどこにも見つかりません。

利用可能な情報は非常に矛盾していますが、そのようなシステムを展開する最も一般的な方法は、すべてのプログラムをrecompilingして、パスを使用するすべての呼び出しがopen(2)のように、ユーザー空間でリダイレクトできます(その時点で共有ライブラリはありませんでした)。

おそらく何百ものそのようなハック( scratchbox は私が使用しなければならないという不快感があった最近のハッキングです)だったので、POSIX標準でそれを収容する必要性を感じた理由はまったく明確ではありません。

2
mosvy

ここで述べた他のすべての理由を超えて、それはdesign simpleであり、UNIXが知られているものです。すべてのディレクトリには..が含まれています。特別なケースとしては、暗闇に潜む危険性(セキュリティまたは堅牢性のため)が常につまずきます。したがって、プログラマーに多くの場所で1つのまれなケースを処理するように強いる代わりに、すべてのディレクトリは.および..エントリーを持つように設計され、均一に処理され、/で何が起こるかを考慮します必要ありません。

1
countermode