Fiz um link simbólico para um executável com
ln -s /usr/bin/mydir/myexec /usr/bin/myexec
Quando executei myexec
no Bash, ele não carrega os arquivos apropriados que estão localizados no myexec
diretó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/myexec
serã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/mydir
naquele 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 -f
retornará 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/myexec
que 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