Cómo determinar la ruta de acceso absoluta a un archivo en un script de shell

2

Estoy escribiendo un script genérico que puede pasar rutas absolutas y relativas (al directorio de trabajo actual) a los archivos existentes.

Necesito una forma a prueba de fallas para convertir todas esas rutas pasadas en rutas absolutas porque necesito pasar las rutas al comando "abrir", que no pasará el directorio actual a la aplicación iniciada.

Una de las ideas que tuve fue comprobar si la ruta comienza con una "/", y si no es así, entonces prefiero la ruta de acceso del directorio de trabajo actual.

Sin embargo, me pregunto si hay una solución más inteligente para esto. Además, como no tengo experiencia con el shell scripting y las herramientas relacionadas, ni siquiera sé cómo probar el valor de una variable para comenzar con "/". Estoy buscando una solución portátil para ejecutar en múltiples Mac, por lo que la instalación de herramientas adicionales o la configuración sería menos que ideal.

¿Alguien puede sugerir una secuencia de comandos estándar que use solo herramientas de envío que tome una variable (llamémosla $ ruta) y la convierta en una ruta absoluta si aún no es absoluta?

    
pregunta Thomas Tempelmann 14.02.2013 - 16:55

3 respuestas

2

Una opción sería instalar coreutils y usar greadlink -f . Resuelve los enlaces simbólicos y funciona con /Foo/ o ~/foo.txt si no existen, pero no con /Foo/foo.txt si /Foo/ no existe.

$ brew install coreutils
$ greadlink -f /etc
/private/etc
$ greadlink -f ~/Documents/
/Users/lauri/Documents
$ greadlink -f ..
/Users
$ greadlink -f //etc/..////
/private
$ greadlink -f /Foo
/Foo
$ greadlink -f /Foo/foo.txt
$ 

Esto no resuelve los enlaces simbólicos, y tampoco funciona con /Foo/foo.txt .

abspath() {
  if [ -d "$1" ]; then
    ( cd "$1"; dirs -l +0 )
  else
    ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
  fi
}

abspath /etc # /etc
abspath /Foo/foo.txt # doesn't work
abspath /Foo # works
abspath .
abspath ./
abspath ../
abspath ..
abspath /
abspath ~
abspath ~/
abspath ~/Documents
abspath /\"\ \'
abspath /etc/../etc/
abspath /private//etc/
abspath /private//
abspath //private # //private
abspath ./aa.txt
abspath aa.tar.gz
abspath .aa.txt
abspath /.DS_Store

dirs -l realiza la expansión de tilde. dirs +0 imprime solo el directorio superior si hay otros directorios en la pila. También puedes reemplazar las subshells con algo como old="$PWD" ... cd "$old" .

La función expand_path de Ruby funciona con todas las rutas que no existen, pero no resuelve los enlaces simbólicos.

$ ruby -e 'print File.expand_path ARGV[0]' ~/aa/bb
/Users/lauri/aa/bb$ 
    
respondido por el user495470 14.02.2013 - 17:24
1

No estoy seguro de que esta respuesta sea lo suficientemente amplia para sus necesidades, pero esto es lo que haría ...

--DISCLAIMER: No he probado esto en SH / BASH / Anything, así que solo use esto como marco. ¡Siéntase libre de editar la pregunta después de que la tenga funcionando!

Puedes probar si el argumento del script proporcionado comienza con un carácter que usa algo como if [[ $a == "/*" ]] .

Dado que todas las rutas relativas llevan consigo la suposición de que la ruta de trabajo es el directorio principal, si sabe que la ruta es no ya absoluta, puede usar pwd , asumiendo la secuencia de comandos o el proceso principal no ha cambiado el directorio de trabajo .

Si el problema del cambio del directorio de trabajo es importante, tendrás que usar una función como find .

Algunas notas adicionales que podrían ponerlo en el camino correcto para resolver su problema: enlace

enlace

enlace

¡Espero que esto te ponga en la dirección correcta!

    
respondido por el zwerdlds 14.02.2013 - 17:11
1

No: una ruta es solo una cadena y debes analizarla para decidir si es absoluta o relativa a $ PWD o ~

Consulte estos para obtener más contexto en caso de que mi respuesta sea demasiado breve.

respondido por el bmike 14.02.2013 - 17:12

Lea otras preguntas en las etiquetas