Por que $0=/bin/foo quando /bin é um link simbólico

Por que $0=/bin/foo quando /bin é um link simbólico

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

app.shinclui

source "/usr/bin/lib.sh"

e lib.shinclui

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

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

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

Responder1

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

Portanto, 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 mesmo de um link simbólico ou físico para o próprio arquivo.

Para ser estritamente preciso (graças a @ilkkachu por apontar isso), há uma chance muito 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") ] ...

Responder2

readlink -f /path/to/whateverlhe dirá o caminho canônico (que estará /usr/bin/app.shno seu exemplo).

Dea página de manual:

canonicalize seguindo cada link simbólico em cada componente do nome fornecido recursivamente; todos, exceto o último componente, devem existir

informação relacionada