O executável não consegue encontrar os arquivos corretos quando chamado via link simbólico

O executável não consegue encontrar os arquivos corretos quando chamado via link simbólico

Fiz um link simbólico para um executável com

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

Quando executei myexecno Bash, ele não carrega os arquivos apropriados que estão localizados no myexecdiretório original.

Por que isso está acontecendo e como posso resolver isso? Estou no Fedora 15 x64.

Responder1

Os arquivos chamados com caminhos relativos /usr/bin/mydir/myexecserão pesquisados ​​em relação ao diretório de trabalho atual de onde o script é executado. Provavelmente seu script atualmente só funciona se for executado /usr/bin/mydirnaquele momento.

Uma maneira de resolver isso é fornecer caminhos absolutos para os arquivos incluídos (mas o script precisa ser atualizado se os arquivos desejados forem movidos), ou você precisa descobrir o caminho absoluto dinamicamente com readlink, por exemplo

THISFILE=$(readlink -f -- "${0}")
THISDIR=${THISFILE%/*}
. "${THISDIR}/my_settings_file"
  • readlink -fretornará o alvo do link simbólico.
  • O ${THISFILE%/*}retornará o destino do link simbólico com a parte incluindo e após a última /removida, ou seja, o caminho para o arquivo em questão.
  • ${THISDIR}agora contém o caminho absoluto para o arquivo e pode ser usado como na linha 3.

Presumi que a questão dizia respeito a um script de shell. Outras linguagens podem ter métodos diferentes.


Outra maneira de resolvê-lo que evita o problema mais ou menos completamente é, em vez de vincular simbolicamente o binário em seu caminho, criar um pequeno script /usr/bin/myexecque contenha, por exemplo

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

Responder2

Discordo de @daniel-anderson. Não creio que essas soluções levem em consideração os argumentos do programa chamado adequadamente. Quase todos os executáveis ​​tratam os argumentos do caminho como relativos ao diretório atual, portanto, mesmo passar os argumentos não funcionará.

O único caso em que um programa se comportará de maneira diferente se for chamado a partir de a symlinké se examinar o 0º argumento. Não conheço nenhuma maneira de contornar isso usando um link simbólico. A solução mais simples é criar um script de shell intermediário na forma de:

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

Observe que se por algum motivo bizarro você precisar fornecer um 0º argumento que não esteja realmente onde está, você pode usar exec -a assim:

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

Observe que o argumento "-a" pode não ser estritamente uma especificação POSIX, então usei o bash especificamente. Supondo que você tenha uma pasta ~/bin em seu caminho, o primeiro caso (normal) pode ser realizado rapidamente da seguinte forma:

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

informação relacionada