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 textfileno 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,
whichproporcionará una respuesta sin incluir la resolución de ese enlace. Sirealpathno está instalado por defecto en su sistema, puede encontrarlo aquí .[EDITAR]: Como parece que
realpathno tiene ninguna ventaja sobre loreadlink -fsugerido por Caleb , probablemente sea mejor usar este último. Mis pruebas de tiempo indican que en realidad es más rápido.fuente
realpathviene en su sistema. (Para otros que no lo tienen, puede usarreadlink -frealpathse remonta a antesreadlink -f(e inclusoreadlink, IIRC) estaba en GNU coreutils (había varias herramientas similares alrededor.readlink -feventualmente se convirtió en el estándar de facto);realpathsolo se mantiene por compatibilidad con scripts que aún lo usan.$(dirname "$(which "$0")")sobre$(dirname $0)dondewhichya no está presente? ¿No es lo mismo?readlink -fno parece funcionar en Mac OS X 10.11.6, perorealpathfunciona de inmediato .Mis sistemas no tienen
realpathlo sugerido por rozcietrzewiacz .Puede lograr esto usando el
readlinkcomando. La ventaja de usar esto sobre el análisiswhichu 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
whichsugerencia. La solución normal para esto implica solodirnameo una combinación decdypwden una subshell. Readlink tiene la ventaja aquí.realpathparece ser más o menos una envoltura parareadlink -ftodos modos.realpathes 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 -ehace, pero no es compatiblebusybox readlink, lo que imita el comportamiento de-esu-fopción.$0en la secuencia de comandos será la ruta completa a la secuencia de comandos, ydirnametomará 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 "$0en la secuencia de comandos será la ruta completa a la secuencia de comandos".$0es 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
$0no termine en caracteres de nueva línea, no esté-y$CDPATHno esté configurado (y posiblemente algunos otros casos de esquina si no se buscó el script$PATH).fuente
Siempre uso
whichpara encontrar la ruta completa de un ejecutable desde la RUTA. Por ejemplo:which pythonSi combina esto con el
dirnamecomando, obtendrá:fuente