Tengo un archivo de script bash, que se coloca en algún directorio agregado a $ PATH para que pueda llamar al script desde cualquier directorio.
Hay otro archivo de texto en el mismo directorio que el script. Me pregunto cómo hacer referencia al archivo de texto en el script.
Por ejemplo, si el script es solo para generar el contenido del archivo de texto, cat textfile
no funcionará, ya que cuando se llama al script desde un directorio diferente, no se encuentra el archivo de texto.
Respuestas:
Estos deberían funcionar igual, siempre que no haya enlaces simbólicos (en la expansión de ruta o en el script en sí):
MYDIR="$(dirname "$(realpath "$0")")"
MYDIR="$(dirname "$(which "$0")")"
Una versión de dos pasos de cualquiera de los anteriores:
MYSELF="$(realpath "$0")"
MYDIR="${MYSELF%/*}"
Si hay un enlace simbólico en el camino a su secuencia de comandos,
which
proporcionará una respuesta sin incluir la resolución de ese enlace. Sirealpath
no está instalado por defecto en su sistema, puede encontrarlo aquí .[EDITAR]: Como parece que
realpath
no tiene ninguna ventaja sobre loreadlink -f
sugerido por Caleb , probablemente sea mejor usar este último. Mis pruebas de tiempo indican que en realidad es más rápido.fuente
realpath
viene en su sistema. (Para otros que no lo tienen, puede usarreadlink -f
realpath
se remonta a antesreadlink -f
(e inclusoreadlink
, IIRC) estaba en GNU coreutils (había varias herramientas similares alrededor.readlink -f
eventualmente se convirtió en el estándar de facto);realpath
solo se mantiene por compatibilidad con scripts que aún lo usan.$(dirname "$(which "$0")")
sobre$(dirname $0)
dondewhich
ya no está presente? ¿No es lo mismo?readlink -f
no parece funcionar en Mac OS X 10.11.6, perorealpath
funciona de inmediato .Mis sistemas no tienen
realpath
lo sugerido por rozcietrzewiacz .Puede lograr esto usando el
readlink
comando. La ventaja de usar esto sobre el análisiswhich
u otras soluciones es que incluso si una parte de la ruta o el nombre de archivo ejecutado fuera un enlace simbólico, podría encontrar el directorio donde estaba el archivo real.Su archivo de texto podría leerse en una variable como esta:
fuente
which
sugerencia. La solución normal para esto implica solodirname
o una combinación decd
ypwd
en una subshell. Readlink tiene la ventaja aquí.realpath
parece ser más o menos una envoltura parareadlink -f
todos modos.realpath
es diferentereadlink -f
. Solo puedo ver que me da los mismos resultados (en lugar dewhich
).readlink -f
(de GNU coreutils) NO requiere que exista el último elemento de la ruta, loreadlink -e
hace, pero no es compatiblebusybox readlink
, lo que imita el comportamiento de-e
su-f
opción.$0
en la secuencia de comandos será la ruta completa a la secuencia de comandos, ydirname
tomará una ruta completa y le dará solo el directorio, para que pueda hacer esto al archivo de texto cat:fuente
realpath $0
, está equivocado al decir que "$0
en la secuencia de comandos será la ruta completa a la secuencia de comandos".$0
es el comando que fue ejecutado, que puede ser, por ejemplo../script.sh
.$(dirname "$0")
devuelve la ruta relativa al script, como parte del comando invocado, no la ruta absoluta. Esto puede generar problemas en los scripts que cambian los directorios mientras se ejecutan.Puedes poner esto en la parte superior de tu script:
Fuente: http://mywiki.wooledge.org/BashFAQ/028
fuente
Estaba probando esto y Realpath no funcionó para mí. La solución con la que fui es:
Lo que ha funcionado bien hasta ahora. Me gustaría saber si hay algún problema potencial con el enfoque.
fuente
SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
Yo suelo:
Que es POSIX y debería funcionar siempre que el nombre de directorio de
$0
no termine en caracteres de nueva línea, no esté-
y$CDPATH
no esté configurado (y posiblemente algunos otros casos de esquina si no se buscó el script$PATH
).fuente
Siempre uso
which
para encontrar la ruta completa de un ejecutable desde la RUTA. Por ejemplo:which python
Si combina esto con el
dirname
comando, obtendrá:fuente