Por que $ 0 = / bin / foo quando / bin é um symlink

1

Eu instalei meus scripts bash em /usr/bin/app.sh e /usr/bin/lib.sh

app.sh inclui

source "/usr/bin/lib.sh"

e lib.sh incluem

if [ "/usr/bin/app.sh" == "$0"] ...

Quando executo app.sh do shell, esse teste falha porque $0 é realmente /bin/app.sh . No sistema de arquivos, /bin é um link simbólico para /usr/bin

Qual é a melhor maneira de o lib.sh determinar se está sendo incluído por app.sh (em oposição a other-app.sh ) de tal forma que não seja enganado pelo ambiente? Eu teria pensado que caminhos absolutos sem links simbólicos teriam feito o trabalho, mas aparentemente não.

    
por spraff 21.10.2016 / 14:01

2 respostas

2

Para verificar se dois arquivos são iguais, você precisa verificar o número do índice (inode), que é exibido com:

stat -L -c %i FilePath

Então o seu cheque agora se torna:

if [ $(stat -L -c %i "/usr/bin/app.sh") == $(stat -L -c %i "$0") ] ...

Isso funciona independentemente de quaisquer links no caminho do diretório, ou até mesmo um link simbólico ou físico para o arquivo em si.

Para ser estritamente preciso (graças a @ilkkachu por apontar isto), há uma chance improvável de que dois arquivos diferentes com o mesmo nome possam ter o mesmo inode em dois sistemas de arquivos diferentes. Para evitar isso, inclua o número do dispositivo na comparação:

if [ $(stat -L -c %d:%i "/usr/bin/app.sh") == $(stat -L -c %d:%i "$0") ] ...
    
por 21.10.2016 / 14:21
3

readlink -f /path/to/whatever informará o caminho canônico (que será /usr/bin/app.sh em seu exemplo).

De a página de manual :

canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist

    
por 21.10.2016 / 14:07