La ubicación del script de origen no está disponible a menos que esté utilizando un shell que ofrece extensiones a la especificación POSIX. Puede probar esto con el siguiente fragmento:
env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included
donde included.sh
contiene
echo "$0"
set
En bash, el nombre del script de origen está en $BASH_SOURCE
. En zsh (en modo de compatibilidad zsh, no en modo de compatibilidad sh o ksh), está en $0
(tenga en cuenta que en una función, $0
es el nombre de la función en su lugar). En pdksh y dash, no está disponible. En ksh93, este método no revela la solución, pero la ruta completa al script incluido está disponible como ${.sh.file}
.
Si requerir bash o ksh93 o zsh es lo suficientemente bueno, puede usar este fragmento:
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
Puede intentar adivinar la ubicación del script mirando qué archivos ha abierto el shell. Experimentalmente, esto parece funcionar con dash y pdksh, pero no con bash o ksh93, que al menos para un script corto han cerrado el archivo de script para cuando llegan a ejecutarlo.
open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
if [ -n "$open_file" ]; then
# best guess: $open_file is this script
fi
Es posible que el script no sea el archivo con el descriptor con el número más alto si el script se origina dentro de un script complejo que se ha estado jugando con redireccionamientos. Es posible que desee recorrer los archivos abiertos. No se garantiza que esto funcione de todos modos. La única forma confiable de localizar un script de fuente es usar bash, ksh93 o zsh.
Si puede cambiar la interfaz, entonces, en lugar de obtener su script, haga que imprima un fragmento de shell para que se lo pase a eval
la persona que llama. Esto es lo que suelen hacer los scripts para establecer variables de entorno. Permite que su script se escriba independientemente de los caprichos del shell y la configuración de shell del llamante.
#!/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
En la persona que llama: eval "`/path/to/setenv`"