相対ファイルパスの絶対パスを取得するbashに組み込みコマンドがありますか?

相対ファイルパスの絶対パスを取得するbashに組み込みコマンドがありますか?

外部コマンドを使用してrealpathファイルの絶対パスを取得できます。

realpath tmp/toto

返品

/home/john/tmp/toto

bash組み込み関数を使用して同じ効果を得ることはできますか?

ベストアンサー1

シェルには、bash相対パス名が与えられた場合に絶対パスを明示的に取得する組み込み方法はありません。

zshシェルでは、次のことができます。

pathname=../../home/kk/.zshenv
print -r -- $pathname:P

そして返します/home/kk/.zshenv(可能であれば、同様の方法ですべてのシンボリックリンクも解決されることに注意してくださいrealpath())。

では、bashディレクトリではなくパス名を指定でき、親ディレクトリへの検索アクセス権があると仮定する場合は、次のようにします。

$ pathname=../../home/kk/.zshenv
$ ( OLDPWD=- CDPATH= cd -P -- "${pathname%/*}" && printf '%s/%s\n' "$PWD" "${pathname##*/}" )
/home/kk/.zshenv

つまり、ファイルが一時的に格納されている(サブシェル上の)ディレクトリは、その値とパス名のファイル名部分をcd使用して絶対パス名を設定するために使用されます。部品を特別に取り扱うことは避けてください$PWD。ディレクトリ自体のシンボリックリンクコンポーネントを解決する副作用があります。ただし、ファイル自体がシンボリックリンクである場合(s修飾子とは異なり)、解決されません。-Pcd..zsh:P

私たちは代わりにを使用してこの問題をOLDPWD解決し始めました(このトリックは機能しますが、他のすべての実装では機能しません)。-cd -P -- -chdir($OLDPWD)chdir("-")bashsh

ディレクトリパスがより簡単です。

$ pathname=../../home/kk
$ ( OLDPWD=- CDPATH= cd -P -- "$pathname" && pwd )
/home/kk

便宜上、これは明らかにシェル関数に含めることができる。

myrealpath () (
    if [[ -d $1 ]]; then
        OLDPWD=- CDPATH= cd -P -- "$1" && pwd
    else
        OLDPWD=- CDPATH= cd -P -- "${1%/*}" && printf '%s/%s\n' "$PWD" "${1##*/}"
    fi
)

(呼び出しシェルの作業ディレクトリが変更されないようにするために、関数全体がサブシェルで定義されています。)

この機能をテストしてみてください。

$ myrealpath ../../home/kk
/home/kk
$ myrealpath ../../home/kk/.zshenv
/home/kk/.zshenv

オペレーティングシステムによっては、パラメータなしで関数を使用すると、現在のディレクトリの絶対パスが返されるか、エラーが発生します。将来のリリースではエラーがPOSIXの要件になるため、bashこれはすべてのシステムのバグになる可能性があります。cd ''

おすすめ記事