Mac OS Xのシェルスクリプトで絶対ファイル名を取得するにはどうすればよいですか?


19

現在実行されているスクリプトファイルの絶対ファイル名を取得したいと思います。リンクも解決する必要があります。

Linuxでは、これは次のように行われるようです。

$(readlink -mn "$0")

しかし、readlink動作しているように非常にはMac OS X上では異なります

私はこれを使用して行われたことを読みました

$(realpath $0)

BSDでも動作しません。Mac OS Xにはありませんrealpath

何か案が?


1
SOでこの質問を参照してください:stackoverflow.com/questions/799679/…–
Telemachus


回答:


19

私はこのことのためにperlをごまかす:

#!/bin/bash
dirname=`perl -e 'use Cwd "abs_path";print abs_path(shift)' $0`
echo $dirname

あなたは私がperlでスクリプト全体を書くだろうと思うだろう、そして私はしばしばそうするが、いつもではない。


これは動作します、どうもありがとう。私はできるだけ早くあなたに賛成票を差し上げます。これを行うための「純粋なシェル」の方法はありますか?
湖西2009

1
私はこれが得られるのと同じくらい良いと思う。(1がGoogleで見つけることができる多くの複数行の「純粋なシェル」のハックを考える。)
Arjan

別の可能性は(いです​​が) '..'パスをトラバースし、 '..'がちょうどあなたが持っていたのと同じファイルを返すまで(再帰または配列を介して)記憶し、それからアセンブルに戻ることです。あなたが行くようにパス。LegatoのNetworkerバックアップソフトウェアがstraceでこれを「真の」パス(ただし、絶対ではない)を取得する方法として実行しているのを見てきました。しかし、上記よりもはるかに多くのコードになります。
ericslaw 09

なぜ誰かが$ 0ではなく$ 1を使用するようにコードを変更したのかはわかりません。$ 1はbashスクリプトの最初の引数ではありませんか?最初の引数ではなく、実行中のbashスクリプトへのパスが必要でした。
エリスロー

27
#!/usr/bin/env bash
scriptDir="$(cd "$(dirname "$0")" && pwd -P)"

MacOSXでも動作します。
アレクサー

1
これはすごい!他にも多くの複雑すぎる答えが浮かんでいます。
ジェイソンS

3
これは、シンボリックリンク、ディレクトリ内のファイルのではなく、一般的にはシンボリックリンクファイルのために働く
ゲルハルト・バーガー

1
またunset -v CDPATH、CDPATHが設定されている場合、cdは不要な出力を引き起こす可能性があるため、cdより前にすると便利です。
バイナリフィール

ファイルのシンボリックリンクの少なくとも一つの層に対処するために、あなたもREADLINKと互換性のある方法でのテストは、(Macは-f持っていない)ことができます: scriptDir=$(unset -v CDPATH; cd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE)")" && pwd -P)
バイナリPhile

0

これはシンボリックリンクのコンボを処理し、ファイルとフォルダーで機能します:

#!/usr/bin/env bash
realpath()
{
    if ! pushd $1 &> /dev/null; then 
        pushd ${1##*/} &> /dev/null
        echo $( pwd -P )/${1%/*}
    else
        pwd -P
    fi
    popd > /dev/null
}

ただし、realpathの--relative-toはサポートしていません。これはここで説明された変換を必要とするでしょう 。


0

別のアプローチ:

# Install.
brew install coreutils

# Use the GNU variant.
grealpath --help
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.