1. ホーム
  2. bash

[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?

2022-03-13 16:19:57

質問

が存在するディレクトリのパスを取得するにはどうすればよいですか? バッシュ スクリプトが配置されています。 内部 そのスクリプトは?

Bashスクリプトを別のアプリケーションのランチャーとして使いたいのですが、どうすればいいですか?作業ディレクトリをBashスクリプトのあるディレクトリに変更し、そのディレクトリのファイルを操作できるようにしたいのですが、以下のような方法があります。

$ ./application

解決方法は?

#!/usr/bin/env bash

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

は便利なワンライナーで、どこから呼び出されてもスクリプトの完全なディレクトリ名を表示します。

この方法は、スクリプトを見つけるためのパスの最後のコンポーネントがシンボリックリンクでない限り機能します (ディレクトリリンクは問題ありません)。 スクリプト自体へのリンクも解決したい場合は、複数行のソリューションが必要です。

#!/usr/bin/env bash

SOURCE=${BASH_SOURCE[0]}
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
  SOURCE=$(readlink "$SOURCE")
  [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )

この最後のものは、エイリアスのどのような組み合わせでも動作します。 source , bash -c やシンボリックリンクなど。

注意してください。 もし cd を別のディレクトリに移動してからこのスニペットを実行すると、結果が不正確になる可能性があります!

また $CDPATH ゲッチュ また、ユーザが cd を賢くオーバーライドして出力を標準エラーにリダイレクトしている場合、標準エラー出力の副作用もあります (エスケープシーケンスを含む。 update_terminal_cwd >&2 Macの場合)。追加 >/dev/null 2>&1 の末尾にある cd コマンドを使えば、両方の可能性に対処できます。

どのように動作するかを理解するために、より冗長なこのフォームを実行してみてください。

#!/usr/bin/env bash

SOURCE=${BASH_SOURCE[0]}
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  TARGET=$(readlink "$SOURCE")
  if [[ $TARGET == /* ]]; then
    echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
    SOURCE=$TARGET
  else
    DIR=$( dirname "$SOURCE" )
    echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
    SOURCE=$DIR/$TARGET # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
  fi
done
echo "SOURCE is '$SOURCE'"
RDIR=$( dirname "$SOURCE" )
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
if [ "$DIR" != "$RDIR" ]; then
  echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"

といった感じで表示されます。

SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'