El ejecutable no puede encontrar los archivos correctos cuando se llama a través de un enlace simbólico

El ejecutable no puede encontrar los archivos correctos cuando se llama a través de un enlace simbólico

Hice un enlace simbólico a un ejecutable con

ln -s /usr/bin/mydir/myexec /usr/bin/myexec

Cuando ejecuté myexecen Bash, no carga los archivos adecuados que se encuentran en el myexecdirectorio original.

¿Por qué sucede esto y cómo puedo solucionarlo? Estoy en Fedora 15 x64.

Respuesta1

Los archivos que se llaman con rutas relativas /usr/bin/mydir/myexecse buscarán en relación con el directorio de trabajo actual desde donde se ejecuta el script. Probablemente su script actualmente solo funcione si se ejecuta en /usr/bin/mydireste momento.

Una forma de resolver esto es proporcionando rutas absolutas a los archivos incluidos (pero luego el script debe actualizarse si los archivos deseados alguna vez se mueven), o necesita encontrar la ruta absoluta dinámicamente con readlink, por ejemplo

THISFILE=$(readlink -f -- "${0}")
THISDIR=${THISFILE%/*}
. "${THISDIR}/my_settings_file"
  • readlink -fdevolverá el destino del enlace simbólico.
  • Devolverá ${THISFILE%/*}el destino del enlace simbólico con la parte que incluye y después de la última /eliminación, es decir, la ruta al archivo en cuestión.
  • ${THISDIR}ahora contiene la ruta absoluta al archivo y se puede utilizar como en la línea 3.

Supuse que la pregunta se refería a un script de shell. Otros idiomas pueden tener métodos diferentes.


Otra forma de resolverlo que evita el problema más o menos por completo es, en lugar de vincular simbólicamente el binario en su ruta, crear un pequeño script que /usr/bin/myexeccontenga, por ejemplo,

#!/bin/sh
cd /usr/bin/mydir
./myexec

Respuesta2

No estoy de acuerdo con @daniel-anderson. No creo que esas soluciones tengan en cuenta adecuadamente los argumentos del programa llamado. Casi todos los ejecutables tratan los argumentos de la ruta como relativos al directorio actual, por lo que ni siquiera pasar los argumentos funcionará.

El único caso en el que un programa se comportará diferente si se llama desde a symlinkes si examina el argumento 0. No conozco ninguna forma de solucionar este problema mediante un enlace simbólico. La solución más sencilla es crear un script de shell intermedio en forma de:

#!/bin/sh
/path/to/executable/that/needs/0th/argument/to/be/actual/path $@

Tenga en cuenta que si por alguna extraña razón necesita darle un argumento 0 que en realidad no está donde está, puede usar exec -a así:

#!/bin/bash
(exec -a /path/to/executable/to/fool /path/to/fool/executable/with $@)

Tenga en cuenta que el argumento "-a" puede no ser estrictamente una especificación POSIX, por lo que utilicé bash específicamente. Suponiendo que tiene una carpeta ~/bin en su ruta, el primer caso (normal) se puede resolver rápidamente de esta manera:

echo -e '#!/bin/sh\n/path/to/executable $@' > ~/bin/shortcut
chmod 755 ~/bin/shortcut
shortcut

información relacionada