La variable $ 0 contiene la información de ruta del script.
- ¿Cómo puedo cambiar la información de ruta a ruta absoluta? Me refiero a cómo procesar ~,., .. o similar?
- ¿Cómo puedo dividir la información de la ruta en el directorio y el nombre del archivo?
Podría usar python / perl para esto, pero quiero usar bash si es posible.

Respuestas:
No necesita procesar cosas como
~, el shell lo hace por usted. Es por eso que puede pasar~/filenamea cualquier script o programa y funciona: todos esos programas no se manejan~solos, su shell convierte el argumento/home/username/filenamey lo pasa al programa en su lugar:Si necesita un nombre de archivo canónico (uno que no incluya cosas como
..), userealpath(gracias Neil ):En cuanto a dividir la ruta en el nombre del directorio y el nombre del archivo, use
dirnameybasename:fuente
realpathes mejor, peroreadlinkparece funcionar cuando lo intento; ¿Conoces un ejemplo donde falla?cd /tmp; touch foo; ln -s foo bar; cd; readlink /tmp/bar. Esto vuelvefooyrealpathvuelve/tmp/foo, que es lo que quieres.readlink -f(nota-f) es casi equivalente arealpath, y es más portátil:readlink -fen GNU coreutils y también existe en algunos otros sistemas;realpathse empaqueta por separado y es posible que no se instale (por ejemplo, solo 5 paquetes no tan comunes dependen de él en Ubuntu 10.04 o Debian lenny).Usar dirname y basename como lo menciona Michael debería ser la forma más segura de obtener lo que desea.
De todos modos, si realmente quieres hacer esto con "bash only tools", puedes usar la sustitución de parámetros:
Este ejemplo está tomado directamente de la Guía avanzada de secuencias de comandos Bash que vale la pena echarle un vistazo.
La explicación es bastante simple:
Mire el patrón como una expresión regular y el
#o##como algún tipo de modificador codicioso / no codicioso.Esto podría ser útil si tendrá que hacer algunas extracciones más complicadas de una parte de rutas.
fuente
${...##...}y amigos en lugar dedirnameybasenameque no funcionan en todos los casos. Por ejemplo, ambos${0##*/}y${0%/*}expandir a la misma como$0si$0no contiene a/.${0%/*}no es una buena alternativa paradirname. Sin embargo, ¿qué tiene de malo usar en${0##*/}lugar debasename?$0es un nombre de directorio con un final/. Pero lamento mi consejo, porquedirnameno hay nada mejor.realpathes un comando que le indica la ruta real (elimina ... y enlaces simbólicos, etc.)Es estándar con FreeBSD. Según esta discusión, también está disponible para Linux:
http://www.unix.com/shell-programming-scripting/89294-geting-real-path.html
Esa discusión también ofrece una solución bash:
fuente