私は仕事をしています。パスの数学的説明(ファイルパスに似ていますが、より抽象的で一般的な場合もあります)
定義する最も要求の厳しいものの1つは、..
(リンクされた投稿のψ)動作、特にシンボリックリンクと対話する方法です。
POSIXルールを正しく理解していることを確認したいと思います。
POSIX 4.14説明する
プロセスが既存のディレクトリエントリのパス名を解決する場合、フルパス名は次のように解決する必要があります。プロセスがパス名を解決した直後に作成されたディレクトリエントリのパス名を解決すると、最後のコンポーネントのパスプレフィックスのすべてのコンポーネントが解決されると、パス名解決が終了します。その後、プロセスは最終コンポーネントを生成する役割を担います。 ...パス名の各ファイル名は、前のファイルで指定したディレクトリにあります(たとえば、パス名フラグメントa / bでは、ファイルbはディレクトリaにあります)。 ...パス名の検証中にシンボリックリンクが見つかった場合...システムは、残りのパス名(存在する場合)の前にシンボリックリンクの内容を追加する必要があります。解決されたパス名は、生成されたパス名の解決でなければなりません。生成されたパス名がで始まらない場合、パス名の最初のファイル名の前のエントリはシンボリックリンクを含むディレクトリとして扱われます。特殊ファイル名ポイントは、前のトピックで指定したディレクトリを参照する必要があります。特殊ファイル名dot-dotは、古いファイルの親ディレクトリを参照する必要があります。特別な場合には、ルートディレクトリのドットポイントはルートディレクトリ自体を参照できます。 ..
だから私の理解は..
POSIXは、親ディレクトリに接続する前にシンボリックリンクを拡張する必要があると言います。
そうですか?
したがって、正規化されたパスの場合、POSIX互換方式は次のようになります。
realpath -P
これを行うには、すべてのディレクトリが存在する必要があり(最終ファイルコンポーネントではない)、左から右に展開してシンボリックリンク(一度発生した場合)を確認して適用します。..
つまり、パスを処理するすべての段階でファイルシステムを読み取る必要があります。
これを次の動作と対比できます。node.jsPath.normalize
(またはPath.posix.normalize
) - 多くのプログラミング言語では、これはかなり正常なものだと思います。Python2そしてサム os.path
似ています)。これはrealpath -s -m
、つまり、一部のディレクトリがsimlinkでも存在しない可能性もあることを完全に無視します。
ファイルシステムにまったく触れる必要がないので良いです。
このように正規化されたパスを取得し、ファイルシステムに到達する関数に提供することは、fs.readFile
正規化されたパスを使用するのと同じですrealpath -L
。「symlinkの前に解決する..
」
また、Bash はフラグを指定しない限り、引数を処理したかのcd
ように動作します。realpath -L
-P
POSIX仕様とrealpath
多くの(ほとんど?)プログラミング言語パスライブラリとの関係を正しく理解していますか?
realpath
ボーナス質問:-P、POSIXと互換性のある正式な実装を持つプログラミング言語/ライブラリ(このようなシェルユーティリティを使用することを除く)の例を持っている人はいますか? (Python 3私は信じるpathlib.Path.resolveそうだね相対パスを絶対パスに変換することもあります。 )
答え1
POSIX仕様の理解は正確です。これは、ディレクトリが他の名前のノードを指すファイルシステムのノードにすぎないという観点からは意味があります。.
の特殊ノードは、パス..
(文字列)ではなくリテラルノードを指します。
ほとんどのプログラミングライブラリパス文字列操作関数はファイルシステムの実際の内容とは関係がないため、文字列操作で正規化する必要があります。これの利点は、存在しないパスまたは読み取り権限のないパスを正規化できることです。
POSIX 方式でパスを正規化するには、..
相対パスではなく絶対パスを使用して正規化する必要があります。そうでなければ意味がありません。シンボリックリンクパスは、相対パスがもはや意味を持たないか、到達するために別のパスを必要とするファイルシステムのまったく異なる部分を指すことがあります..
。必要に応じて、readlinkといくつかのルールを使用して相対パスが利用可能かどうかを確認できますが、パスライブラリにはこの問題を解決する機能がないと思います。
答え2
.
Unixの..
親ディレクトリに属する物理ファイル(ファイルまたはディレクトリ)を表す物理ディレクトリエントリ。
..
パスの最後のセグメントを削除するために使用されるパス解析キーワードではありません。を解析するには、..
まずそのエントリを含むディレクトリを解析する必要があります。 Nodejsが間違っています。
$ mkdir -p /tmp/foo/bar/baz
$ ln -s /tmp/foo/bar/baz /tmp/symlink
$ realpath /tmp/symlink/..
/tmp/foo/bar
$ node -e 'console.log(path.normalize("/tmp/symlink/.."))'
/tmp
(このエントリはディレクトリの作成時に常に作成され、現在のディレクトリと親ディレクトリへのハードリンクとして使用されます。これはまれな例です。ディレクトリハードリンクこれは、通常、通常のユーザーがディレクトリのハードリンクを作成することを許可しないためです。
ls -ld
これがサブディレクトリを作成するたびにディレクトリのハードリンク数が増加する理由であり、ディレクトリが3(名前、.、および_name / ..)のハードリンク数で始まる理由です。サブディレクトリは..
現在のディレクトリへのハードリンクなので、ハードリンクの数が増えます。 )