Hice un enlace simbólico a un ejecutable con
ln -s /usr/bin/mydir/myexec /usr/bin/myexec
Cuando ejecuté myexec
en Bash, no carga los archivos adecuados que se encuentran en el myexec
directorio 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/myexec
se 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/mydir
este 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 -f
devolverá 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/myexec
contenga, 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 symlink
es 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