スクリプトで絶対パスを探す

スクリプトで絶対パスを探す

スクリプトから$0可能な相対パスを取得します。それを絶対値に変換するために理解していない次の解決策を見つけました。

abspath=$(cd ${0%/*} && echo $PWD/${0##*/})

${0%/*}私の問題は内部の魔法と${0##*/}。前者はディレクトリ名を抽出し、後者はファイル名を抽出するようですが、どうなるかわかりません。

答え1

Seanには最も簡単な解決策がありますreadlink -f $0。奇妙なファイル名を処理することについて確実に知りたい場合は、次のことを使用できます。

absolute_path_x="$(readlink -fn -- "$0"; echo x)"
absolute_path="${absolute_path_x%x}"

文書

答え2

定義:

${string%substring}$substringの終わりから最短一致が削除されました$string

${string##substring}$substringの先頭から最も長い一致が削除されました$string

あなたの例:

abspath=$(cd ${0%/*} && echo $PWD/${0##*/})

${0%/*}最後のスラッシュの後のすべてのエントリを削除して、スクリプトのディレクトリ名(相対パスである可能性があります)を指定します。

${0##*/}最後のスラッシュの前のすべてのエントリを削除し、スクリプト名のみを指定します。

したがって、このコマンドはスクリプトのディレクトリに変更し、$PWD現在の作業ディレクトリ(提供)とスクリプト名を関連付けて絶対パスを提供します。

何が起こっているかを確認するには、次のことを試してください。

echo ${0%/*}
echo ${0##*/}

答え3

タスクを実行するより安全で読みやすい方法は次のとおりです。

abspath=$(unset CDPATH && cd "$(dirname "$0")" && echo $PWD/$(basename "$0"))

メモ:

  • 以前のパスを持たないファイル名のみが存在する場合、元のスクリプトは$0失敗しますが、ここに提供されているスクリプトは機能します。 (問題ではありませんが、$0他のアプリでは発生する可能性があります。)
  • ファイルパスが実際に存在しない場合、どちらの方法も失敗します。 (では問題ではありませんが、$0他のアプリケーションでは問題になる可能性があります。)
  • unsetユーザーが設定した場合はCDPATH必須です。
  • readlink -fまたはとは異なり、realpathこれはLinux以外のバージョンのUnix(Mac OS Xなど)に適用されます。

答え4

bash 組み込みコマンド pwd を紹介します。 GNU coreutilsパッケージにもあります。

$ sh ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
$0: ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
cheeky binary from /home/jaroslav/tmp (/home/jaroslav/tmp)

$ cat /home/jaroslav/tmp/somewhere.sh

abs=$( cd `dirname "$0"` ; pwd -P)
absBin=$( cd `dirname "$0"` ; /bin/pwd -P)
echo \$0: $0
echo cheeky binary from $abs \($absBin\)

関連情報