スクリプトから絶対パスを見つける


10

スクリプトで$0は、可能な相対パスを取得します。それを絶対に変換するために、私は理解できないこの解決策を見つけました:

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

私の問題は、内部の魔法である${0%/*}${0##*/}。前者はdirnameを抽出し、後者はファイル名を抽出するように見えますが、方法はわかりません。


2
これはパラメーター拡張を使用しますが、私にはうまくいきませんでした。スクリプトがLinuxでのみ使用される場合は、を使用readlink -f $0して正規パスを取得できます。
Shawn J. Goff

1
@Shawn:正しい考え方を導入したため、1件の素晴らしいコメント投票:「これはパラメーター拡張を使用していますが、私には機能しませんでした」。dirnameutilのは、ここに便利です。
D4RIO 2011年

mywiki.wooledge.org/BashFAQ/028cyberciti.biz/faq/...は言うBASH_SOURCEよりも優れている$0、として$0、現在実行中のスクリプトではないかもしれませんコマンドで入力したユーザーのは、提供します。
Joel Purra 2014年

回答:


8

定義:

${string%substring}$substringの末尾からの 最短一致を削除し$stringます。

${string##substring}$substringの最初からの最長一致を削除し$stringます。

あなたの例:

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

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

${0##*/} 最後のスラッシュまでをすべて削除し、スクリプトの名前だけを与えます。

したがって、このコマンドはスクリプトのディレクトリに移動し、現在の作業ディレクトリ(で指定$PWD)と絶対パスを与えるスクリプトの名前を連結します。

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

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

シェルの特殊文字を含む(ほとんどすべての)ファイル名に対処するために、すべての変数展開を二重引用符で囲みます。
Gilles 'SO-悪をやめる'

10

Shawnは最も簡単な解決策を持っていましたreadlink -f $0。奇妙なファイル名を確実に処理したい場合は、これを使用できます。

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

ドキュメンテーション


1
最終的な改行が正しく処理されるのを確認してください。残念ながら、これreadlink -fnはLinux、NetBSD、OpenBSDに固有のものです。
Gilles「SO-邪悪なことをやめなさい」

4

この作業を行うためのより安全で読みやすい方法を次に示します。

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

ノート:

  • $0が前のパスのない裸のファイル名の場合、元のスクリプトは失敗しますが、ここで指定したスクリプトは機能します。(問題はありません$0が、他のアプリケーションで発生する可能性があります。)
  • ファイルへのパスが実際に存在しない場合、どちらのアプローチも失敗します。(では問題ありません$0が、他のアプリケーションで発生する可能性があります。)
  • unsetユーザーがCDPATH設定している場合は、これが不可欠です。
  • 違ってreadlink -frealpath、これは、UnixのLinux以外のバージョン(例えば、マックOS X)上で動作します。

2

Shell Parameter Expansionについて学びたい場合は、ここから読むことができますが、Expansionが常に良い選択であるとは限りません。この場合、ほとんどすべてのUnixライクシステムには2つの優れたユーティリティがあります。

basename
dirname

1つ目はファイル名を抽出し、2つ目はパスを抽出するため、$ 0がある場合は次のように記述します。

dirname $0

そして、あなたは道を得るでしょう。

乾杯


dirnameは相対パスを返すことができます
オプティサイクリック2013

0

組み込みの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\)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.