Credo $(dirname "$BASH_SOURCE")
farà quello che vuoi, purché il file che stai cercando non lo sia un collegamento simbolico.
Se il file che stai cercando potrebbe essere un collegamento simbolico, puoi fare qualcosa di simile al seguente per ottenere la vera directory:
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")
Ecco quella che potrebbe essere una soluzione elegante:
script_path="${BASH_SOURCE[0]}"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Ciò, tuttavia, non funzionerà durante l'approvvigionamento di collegamenti. In tal caso, si potrebbe fare
script_path="$(readlink -f "$(readlink "${BASH_SOURCE[0]}")")"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Cose da notare:
- array come
${array[x]}
non sono conformi a POSIX - ma poi, ilBASH_SOURCE
array è comunque disponibile solo in Bash - su macOS, il BSD nativo
readlink
non supporta-f
, quindi potresti dover installare GNUreadlink
utilizzando ad es. brew entrobrew install coreutils
e sostituiscireadlink
digreadlink
- a seconda del tuo caso d'uso, potresti voler utilizzare il
-e
o-m
commuta invece di-f
più possibilmente-n
; vedere la pagina man di readlink per i dettagli
Un approccio diverso al problema, se utilizzi "." per impostare le variabili di ambiente, un altro modo standard per farlo è fare in modo che il tuo script echo i comandi di impostazione delle variabili, ad esempio:
# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar
quindi valuta l'output:
eval $(/path/to/settings.sh)
Ecco come funzionano i pacchetti come i moduli. In questo modo è anche facile supportare le shell derivate da sh (X=...; export X
) e csh (setenv X ...
)