Al escribir un script bash, ¿cómo obtengo la ruta absoluta de la ubicación del archivo actual?

16

Supongamos que tengo un archivo bash llamado myBash.bash. Reside en:

/myDirect/myFolder/myBash.bash

Ahora quiero usar la cadena /myDirect/myFolder(la ubicación de myBash.bash) dentro del script. ¿Hay algún comando que pueda usar para encontrar esta ubicación?

Editar: La idea es que quiero configurar una carpeta zip con código que pueda iniciarse mediante un script bash dentro de ese archivo zip. Sé las rutas de archivo relativas del código dentro de ese archivo zip, pero no las rutas absolutas, y las necesito. Una forma sería codificar en la ruta, o requerir que la ruta del archivo se proporcione como una variable. Sin embargo, me resultaría más fácil si fuera posible que el archivo bash descubriera dónde está solo y luego cree las rutas relevantes al otro archivo a partir de su conocimiento de la estructura del archivo zip.

dimpol
fuente
3
Esto podría ser más adecuado para stackoverflow. Consulte estas preguntas: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/… .
Sethos II
1
usar cómo. por favor aclare
Sergiy Kolodyazhnyy
1
@SethosII esta pregunta es totalmente sobre el tema aquí
Zanna
1
Agregué más contexto a la pregunta. Pensé que podría haber un comando fácil / obvio para obtener la ruta del archivo que se está ejecutando, pero parece que la respuesta es al menos no obvia.
dimpol
3
@Zanna No digo que sea fuera de tema, creo que es más apropiado y como se muestra con los enlaces ya preguntados y respondidos allí varias veces.
Sethos II

Respuestas:

24

Puede obtener la ruta completa como:

realpath "$0"

Y como señaló Serg , puede usar dirnamepara quitar el nombre de archivo como este

dirname "$(realpath $0)"

o incluso mejor para evitar citas incómodas y división de palabras con nombres de archivo difíciles:

temp=$( realpath "$0"  ) && dirname "$temp"

Mucho mejor que mi idea anterior de analizarlo (¡sabía que habría una mejor manera!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Notas

  • realpath devuelve la ruta real de un archivo
  • $0 es este archivo (el script)
  • s|old|new|reemplazar oldconnew
  • \(.*\)/guardar cualquier personaje antes /para más tarde
  • \1 la parte guardada
Zanna
fuente
2
+1 para uso $0y sedmagia. Pero dicha sedmagia es realmente innecesaria cuando dirnameexisten herramientas como esta
Sergiy Kolodyazhnyy
2
ya tienes la respuesta, usa realpath: realpath "$( dirname $0 )"Yo personalmente usaría readlinkpero ese soy yo:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy
@Serg: ¿No dirname "$(realpath "$0")"sería mejor? Por lo general, se desea conocer el directorio principal del archivo referenciado en lugar del directorio principal del enlace simbólico que hace referencia a dicho archivo.
David Foerster
44
@Serg "$(dirname "$(realpath "$0")")"es la forma más sencilla. Las citas dentro del $()trabajo son normales.
Deprimido Daniel
@DepressedDaniel Investigó un poco en línea, tiene razón: $()ser un subshell permitirá tener citas fuera. Sin embargo, no diría que es tan sencillo, a menos que uno se dé cuenta de que $()todos son subcapas
Sergiy Kolodyazhnyy
5

si el script está en tu camino, puedes usar algo como

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDITAR: después de leer los comentarios de Serg, esta podría ser una solución genérica que funciona si el script está en su camino o no.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
Antonello Piemonte
fuente
whiches más adecuado para cuando el script reside en uno de los directorios que forman parte de la PATHvariable. Úselo $0desde un guión, tal como lo muestra Zanna. Pero su respuesta es correcta ya que usa en dirnamelugar de meterse con sed, por lo tanto, +1 para eso
Sergiy Kolodyazhnyy
5

La respuesta aceptada parece perfecta. Aquí hay otra forma de hacerlo:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdimprime la ruta real del directorio, a diferencia del pwdcomando incorporado.

serv-inc
fuente
0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

Se toma como referencia de kenorb y andro.
No dirname, readlink, realpath, BASH_SOURCE
Todos son incorporados

HemanthJabalpuri
fuente