Lokasi skrip bersumber tidak tersedia kecuali jika Anda menggunakan shell yang menawarkan ekstensi ke spesifikasi POSIX. Anda dapat menguji ini dengan cuplikan berikut:
env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included
dimana included.sh
mengandung
echo "$0"
set
Di bash, nama skrip bersumber di $BASH_SOURCE
. Dalam zsh (dalam mode kompatibilitas zsh, bukan dalam mode kompatibilitas sh atau ksh), itu dalam $0
(perhatikan bahwa dalam suatu fungsi, $0
adalah nama fungsi sebagai gantinya). Dalam pdksh dan dash, itu tidak tersedia. Di ksh93, metode ini tidak mengungkapkan solusi, tetapi path lengkap ke skrip yang disertakan tersedia sebagai ${.sh.file}
.
Jika membutuhkan bash atau ksh93 atau zsh cukup baik, Anda dapat menggunakan potongan ini:
if [ -n "$BASH_SOURCE" ]; then
this_script=$BASH_SOURCE
elif [ -n "$ZSH_VERSION" ]; then
setopt function_argzero
this_script=$0
elif eval '[[ -n ${.sh.file} ]]' 2>/dev/null; then
eval 'this_script=${.sh.file}'
else
echo 1>&2 "Unsupported shell. Please use bash, ksh93 or zsh."
exit 2
fi
Anda dapat mencoba menebak lokasi skrip dengan melihat file apa yang dibuka oleh shell. Secara eksperimental ini tampaknya berfungsi dengan tanda hubung dan pdksh tetapi tidak dengan bash atau ksh93 yang setidaknya untuk skrip pendek telah menutup file skrip pada saat mereka mulai menjalankannya.
open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
if [ -n "$open_file" ]; then
# best guess: $open_file is this script
fi
Script mungkin bukan file dengan deskriptor nomor tertinggi jika skrip tersebut bersumber di dalam skrip kompleks yang telah diputar dengan pengalihan. Anda mungkin ingin mengulang-ulang file yang terbuka. Ini tidak dijamin untuk tetap bekerja. Satu-satunya cara yang dapat diandalkan untuk menemukan skrip bersumber adalah dengan menggunakan bash, ksh93 atau zsh.
Jika Anda dapat mengubah antarmuka, maka alih-alih mencari skrip Anda, minta skrip Anda mencetak cuplikan shell untuk diteruskan ke eval
dalam pemanggil. Inilah yang biasanya dilakukan skrip untuk mengatur variabel lingkungan. Ini memungkinkan skrip Anda ditulis secara independen dari keanehan konfigurasi penelepon dan konfigurasi penelepon.
#!/bin/sh
FOO_DIR=$(dirname -- "$0")
cat <<EOF
FOO_DIR='$(printf %s "$FOO_DIR" | sed "s/'/'\\''/g")'
PATH="\$PATH:$FOO_DIR/bin";
export FOO_DIR PATH
EOF
Di penelepon: eval "`/path/to/setenv`"