Cómo Resolver Enlaces Simbólicos en un Script Shell

Trabajar con enlaces simbólicos (o symlinks) en sistemas similares a Unix puede ser complicado a veces, especialmente cuando deseas averiguar la ruta real a la que apunta un symlink. Si estás escribiendo un script de shell y necesitas determinar la ruta completa de un objetivo después de resolver cualquier symlink intermedio, estás en el lugar correcto. En esta publicación del blog, desglosaremos cómo lograr esto de manera eficiente.

Entendiendo el Problema

Imagina que tienes una situación en la que tienes un enlace simbólico foo que apunta a otro directorio bar. Cuando ejecutas comandos como cd foo y pwd, tu shell podría no revelar la estructura subyacente claramente, lo que hace difícil derivar la ruta completa al objetivo.

Por ejemplo:

ls -ld foo bar
drwxr-xr-x   2 greg  greg  68 Aug 11 22:36 bar
lrwxr-xr-x   1 greg  greg   3 Aug 11 22:36 foo -> bar

Si ejecutaras:

cd foo
pwd

La salida sería simplemente /Users/greg/tmp/foo, lo que realmente no te ayuda si tu objetivo es descubrir la ruta real a la que apunta foo, que es /Users/greg/tmp/bar.

La Solución

Afortunadamente, existen comandos incorporados que pueden ayudarte a resolver symlinks en un script de shell sin necesidad de profundizar en programación en C. A continuación, te mostramos cómo hacerlo:

Usando el Comando pwd

El comando pwd -P se utiliza para imprimir el directorio de trabajo actual, resolviendo todos los symlinks para proporcionar la ruta absoluta del objetivo. Cuando ejecutas:

pwd -P

Devolverá la ruta completa después de resolver cualquier symlink.

Usando getcwd

Otra manera de lograr esto es utilizando la función getcwd de la biblioteca unistd.h en C. Sin embargo, si estás haciendo scripting, puedes confiar en comandos de shell en su lugar. Es una buena práctica saber que getcwd tiene un comportamiento similar a pwd -P.

Construyendo la Función de Resolución

Puedes encapsular estos comandos en una función para facilitar tu trabajo. Aquí tienes un ejemplo de una simple función resolve en un shell Bash:

resolve() {
    # Usa la ruta proporcionada y resuélvela
    local target=$1
    # `readlink -f` sigue symlinks, devolviendo la ruta completa
    local full_path=$(readlink -f "$target")
    echo "$full_path"
}

Ejemplo de Uso

Ahora, simplemente llama a la función con:

resolve "foo"

Esto devolverá:

/Users/greg/tmp/bar

Este patrón permite acceder a la ruta completa de cualquier symlink que hayas encontrado en tu entorno de script de shell.

Bonus: Resolviendo Rutas de Usuario Home

Si también quieres resolver directorios home utilizando la notación de tilde (como ~username), Bash expande automáticamente estas rutas en un script de shell, por lo que puedes combinar esto con tu función resolve sin problemas.

Conclusión

Resolver enlaces simbólicos en scripts de shell no tiene que ser complicado. Al utilizar el comando pwd -P o crear una función auxiliar como resolve que utiliza readlink, puedes determinar efectivamente la ruta completa a tu objetivo. Esta habilidad es esencial para cualquier persona que trabaje en un entorno similar a Unix y hace que tus scripts sean mucho más robustos e informativos.

Recuerda, gestionar bien los symlinks puede ahorrarte tiempo y confusión mientras navegas por estructuras de directorios o escribes scripts de shell complejos.