web-dev-qa-db-ja.com

「realpath」と「readlink -f」の違いは何ですか

realpathコマンドの詳細と、readlink -fが推奨されるようになったため、このコマンドがどのように非推奨になったかを読んだことがあります。 realpathが導入された理由は、readlinkにそのような機能がないためであり、いったんそれが導入されると、realpathは不要になり、そのサポートはほとんどのOSベンダーによって中止されたということも、いくつかの場所で見ました。

私の質問の理由は、多くの人がreadlink -frealpathと「かなり似ている」コマンドとして推奨していることも知っているためです。 「かなり似ている」部分。実際の違いは何ですか?

77
Felipe Leão

周りにはいくつかのrealpathコマンドがあります。

realpathユーティリティは、 realpath ライブラリ関数のラッパーであり、多くの times が再発明されました。

Debianは realpath パッケージ( separated from dwww from woody )これは、2001年以降、パッケージとドキュメントに関するもの以外は変更されていませんが、現在は廃止されています。標準ユーティリティ(GNU readlinkおよびすぐにGNU realpath)があるため、このユーティリティは廃止されましたが、GNUユーティリティにはreadlinkさえまったくありませんでした。このrealpathの実装は、シンボリックリンクの解決を防止したり、nullで終了する出力を生成したりするために、いくつかの options をサポートしています。 BusyBox には、独自の realpath コマンドも含まれます(オプションはありません)。

GNU coreutils は、 realpath コマンドを version 8.15 で2012年1月に導入しました。これはBusyBoxとDebianのrealpathの互換性のある代替品であり、GNU readlink と共通の多くのオプションもあります。

realpathreadlink -fと同じ効果があり、GNU readlinkを使用します。 2つのコマンド(またはreadlink -fからのさまざまなrealpathコマンド)を区別するのは、それらがサポートする追加のオプションです。

GNU realpathは非推奨ではありません。それは反対の問題を抱えています:それはどこでも利用可能であるにはあまりに新しいです。 Debianは GNU realpathcoreutils パッケージから省略し、独自のrealpathを使用していました。 GNU realpathはドロップイン置換である必要があるため、理由はわかりません。ただし、Debian jessieおよびUbuntu 16.04以降、GNU realpathが使用されます。

Linuxシステムでは、現時点では、シンボリックリンクを含む可能性のあるパスを正規化する最善の策はreadlink -fです。

BSDシステムには、GNU readlinkとは異なる機能を持つ readlink コマンドがあります。特に、BSD readlinkには、パスを正規化するオプションがありません。渡されたシンボリックリンクをトラバースするだけです。

偶然にも、readlinkには同じ問題がありました。これも 何度も発明されました (UNIXにシンボリックリンクが追加されたときに、このユーティリティを追加しなかったのは残念な省略です)。現在、多くの互換性のないフラグ(特にBSD対GNU)を持ついくつかの実装で安定しています。

tl; drreadlink -fは、既存のディレクトリに存在しないファイルに対して0を返しますが、realpath1を返します。ただし、readlink -erealpathのように動作し、存在しないファイルに対して1を返します(最後の編集者注を参照)。

readlink -f

$ readlink -f non-existent-file
/home/user/non-existent-file
$ echo $?
0

readlink -e

$ readlink -e non-existent-file
$ echo $?
1

realpath

$ realpath non-existent-file
non-existent-file: No such file or directory
$ echo $?
1

readlink -f存在しないディレクトリ

readlink -fの動作は、パスのどの部分が存在しないかによって異なります。

$ readlink -f /tmp/non-existent-dir/foo
$ echo $?
1

realpath存在しないディレクトリ

$ realpath /tmp/non-existent-dir/foo
$ echo $?
1

可用性

readlinkは、ほとんどのLinuxディストリビューションにインストールされています。一方、realpathは明示的にインストールする必要があります。

要約すれば

realpath ...の呼び出しを置き換える場合は、readlink -e ...を使用します。


Ubuntuでreadlink(GNU coreutils)8.21およびrealpath version 1.19でテスト済み16。

編集: @AnthonyGeogheganは「これはrealpathのDebianバージョンを指します。GNUバージョンof realpathreadlink -fと同じように動作します ")

21