Saya percaya $(dirname "$BASH_SOURCE")
akan melakukan apa yang Anda inginkan, selama sumber file yang Anda tidak sebuah symlink.
Jika file yang Anda sumber mungkin merupakan symlink, Anda dapat melakukan sesuatu seperti berikut untuk mendapatkan direktori sebenarnya:
PRG="$BASH_SOURCE"
progname=`basename "$BASH_SOURCE"`
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
dir=$(dirname "$PRG")
Inilah yang mungkin menjadi solusi elegan:
script_path="${BASH_SOURCE[0]}"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Namun, ini tidak akan berfungsi saat mencari tautan. Dalam hal ini, seseorang mungkin melakukannya
script_path="$(readlink -f "$(readlink "${BASH_SOURCE[0]}")")"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Hal yang perlu diperhatikan:
- array seperti
${array[x]}
tidak sesuai dengan POSIX - tetapi kemudian,BASH_SOURCE
array hanya tersedia di Bash - di macOS, BSD asli
readlink
tidak mendukung-f
, jadi Anda mungkin harus memasang GNUreadlink
menggunakan mis. diseduh denganbrew install coreutils
dan gantireadlink
olehgreadlink
- bergantung pada kasus penggunaan Anda, Anda mungkin ingin menggunakan
-e
atau-m
alihkan alih-alih-f
ditambah mungkin-n
; lihat halaman manual readlink untuk detailnya
Masalah yang berbeda - jika Anda menggunakan "." untuk menyetel variabel lingkungan, cara standar lain untuk melakukan ini adalah dengan membuat perintah setelan variabel gema skrip Anda, mis.:
# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar
lalu evaluasi hasilnya:
eval $(/path/to/settings.sh)
Begitulah cara kerja paket seperti modul. Cara ini juga memudahkan untuk mendukung shell turunan dari sh (X=...; export X
) dan csh (setenv X ...
)