Executável não pode encontrar arquivos corretos quando chamado via link simbólico

3

Eu fiz um link simbólico para um executável com

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

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

Por que isso está acontecendo e como posso resolvê-lo? Eu estou no Fedora 15 x64.

    
por Maxwell S. 28.04.2012 / 11:33

2 respostas

3

Os arquivos chamados com caminhos relativos em /usr/bin/mydir/myexec serão pesquisados em relação ao diretório de trabalho atual de onde o script foi executado. Provavelmente seu script atualmente só funciona se for executado a partir de /usr/bin/mydir no momento.

Uma maneira de resolver isso é dando 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 , eg

THISFILE=$(readlink -f -- "${0}")
THISDIR=${THISFILE%/*}
. "${THISDIR}/my_settings_file"
  • readlink -f retornará o destino do link simbólico.
  • O ${THISFILE%/*} retornará o destino do symlink com a parte incluindo e após o último / removido, 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.

Eu assumi a questão em questão um shell script. Outras línguas podem ter métodos diferentes.

Outra maneira de resolvê-lo, evitando o problema mais ou menos, é criar um pequeno script em /usr/bin/myexec que contenha, por exemplo,

#!/bin/sh
cd /usr/bin/mydir
./myexec
    
por 28.04.2012 / 14:33
1

Eu discordo de @ daniel-anderson. Eu não acho que essas soluções levam argumentos para o programa chamado em conta corretamente. Quase todos os executáveis tratam argumentos de caminho como relativos ao diretório atual, portanto, até mesmo passar os argumentos não funcionará.

O único caso em que um programa se comportará de forma diferente se for chamado a partir de um symlink é se ele examina o 0º argumento. Eu não conheço nenhuma maneira de contornar isso usando um link simbólico. O trabalho 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 $@

Note que se por algum motivo bizarro você precisar dar 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 $@)

Note 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 rapidamente executado da seguinte forma:

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