O programa é executado quando acessado diretamente, mas não quando acessado através de link simbólico

O programa é executado quando acessado diretamente, mas não quando acessado através de link simbólico

Instalei um aplicativo Ruby /home/anp/toolse criei um link simbólico da seguinte forma:

ln -s /home/anp/tools/wwan /usr/bin/wwan

Se eu executar ~/tools/wwan, ele funcionará perfeitamente.
Se eu tentar executá-lo a partir do link simbólico, recebo um erro dizendo

não é possível carregar esse arquivo -- lib/wwan

Isso não deveria funcionar como está? O link simbólico está causando problemas quando o programa tenta resolver caminhos de arquivos relativos?

Responder1

O link simbólico está causando problemas quando o programa tenta resolver caminhos de arquivos relativos?

Pode. Muito provavelmente é neste caso.

Cenário plausível quando você executa ~/tools/wwan:

  1. O shell se expande ~e você realmente executa o arquivo /home/anp/tools/wwan.
  2. A ferramenta é iniciada. Ele sabe que é /home/anp/tools/wwan(por exemplo, por causa deargv[0]).
  3. A ferramenta encontra a parte do diretório da string acima e altera seu próprio diretório de trabalho para ela: /home/anp/tools/.
  4. A ferramenta refere-se a um ativo adicional através de um caminho relativo: lib/wwan. O ativo está realmente em /home/anp/tools/lib/wwan, então funciona.

Mas quando você executa /usr/bin/wwanor wwan(com /usr/binbe in $PATH), o cenário começa /usr/bin/wwane termina com /usr/bin/lib/wwanwhich não existe como arquivo. O ativo não está lá.

Os detalhes podem variar, mas esse problema com um link simbólico indica que a ferramenta não desreferencia o link quando deveria. Se assim fosse, sempre funcionaria /home/anp/tools/wwancomo se você executasse /home/anp/tools/wwan. Eu diria que o que você experimentou é um bug.

Uma maneira de lidar com isso é melhorar a própria ferramenta (editar seu código) para que ela encontre corretamente seu caminho real.

Outra maneira é usar um script wrapper em vez de um link simbólico. Remova o link simbólico e crie um script com o nome /usr/bin/wwan. O conteúdo do roteiro:

#!/bin/sh
exec /home/anp/tools/wwan "$@"

Torne-o executável. Agora, se você ligar /usr/bin/wwan, o script irá exece /home/anp/tools/wwanesta será a string com a qual a ferramenta funcionará, então deve funcionar. Todos (zero ou mais) argumentos fornecidos /usr/bin/wwanserão passados /home/anp/tools/wwan​​graças a "$@".

Notas:

  • /usr/bin/é um local em todo o sistema para executáveis. Vincular a partir daí a uma ferramenta que reside em seu diretório inicial não é uma boa prática em geral; o mesmo para embrulhar.
  • Um script wrapper é um arquivo regular separado. Sua propriedade e permissões são independentes daquelas do executável de destino. Acerte-os.

informação relacionada