Il percorso dello script di provenienza non è disponibile a meno che non si stia utilizzando una shell che offre estensioni alla specifica POSIX. Puoi testarlo con il seguente frammento:
env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included
dove included.shcontiene
echo "$0"
set
In bash, si trova il nome dello script di provenienza $BASH_SOURCE. In zsh (in modalità di compatibilità zsh, non in modalità di compatibilità sh o ksh), è in $0(si noti che in una funzione $0è invece il nome della funzione). In pdksh e dash, non è disponibile. In ksh93, questo metodo non rivela la soluzione, ma il percorso completo per lo script incluso è disponibile come ${.sh.file}.
Se richiedere bash o ksh93 o zsh è abbastanza buono, puoi usare questo snippet:
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
Puoi provare a indovinare la posizione dello script guardando quali file ha aperto la shell. A livello sperimentale questo sembra funzionare con dash e pdksh ma non con bash o ksh93 che almeno per un breve script hanno chiuso il file di script quando riescono a eseguirlo.
open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
if [ -n "$open_file" ]; then
# best guess: $open_file is this script
fi
Lo script potrebbe non essere il file con il descrittore con il numero più alto se lo script proviene da uno script complesso che ha eseguito i reindirizzamenti. Potresti voler scorrere i file aperti. Questo non è garantito per funzionare comunque. L'unico modo affidabile per individuare uno script di provenienza è utilizzare bash, ksh93 o zsh.
Se è possibile modificare l'interfaccia, quindi anziché eseguire il sourcing dello script, fare in modo che lo script stampi uno snippet di shell da trasmettere al evalchiamante. Questo è ciò che generalmente fanno gli script per impostare le variabili di ambiente. Consente di scrivere la sceneggiatura indipendentemente dai capricci della configurazione della shell e della shell del chiamante.
#!/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
Nel chiamante: eval "`/path/to/setenv`"