
Eu instalei meus scripts bash /usr/bin/app.sh
e/usr/bin/lib.sh
app.sh
inclui
source "/usr/bin/lib.sh"
e lib.sh
inclui
if [ "/usr/bin/app.sh" == "$0"] ...
Quando executo app.sh
a partir do shell, esse teste falha porque, $0
na verdade, é /bin/app.sh
. No sistema de arquivos, /bin
há um link simbólico para/usr/bin
Qual é a melhor maneira de lib.sh
determinar 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/whatever
lhe dirá o caminho canônico (que estará /usr/bin/app.sh
no seu exemplo).
canonicalize seguindo cada link simbólico em cada componente do nome fornecido recursivamente; todos, exceto o último componente, devem existir