
Ich habe meine Bash-Skripte installiert /usr/bin/app.sh
und/usr/bin/lib.sh
app.sh
beinhaltet
source "/usr/bin/lib.sh"
und lib.sh
beinhaltet
if [ "/usr/bin/app.sh" == "$0"] ...
Wenn ich es app.sh
von der Shell aus ausführe, schlägt dieser Test fehl, weil $0
es sich tatsächlich um einen symbolischen Link handelt /bin/app.sh
. Auf dem Dateisystem /bin
befindet sich ein symbolischer Link zu/usr/bin
Wie kann man am besten feststellen, ob es von (im Gegensatz zu ) lib.sh
eingeschlossen wird, und zwar so, dass es nicht von der Umgebung ausgetrickst wird? Ich hätte gedacht, dass absolute Pfade ohne symbolische Links den Job erledigen würden, aber das ist anscheinend nicht der Fall.app.sh
other-app.sh
Antwort1
Um zu überprüfen, ob zwei Dateien gleich sind, müssen Sie die Indexnummer (Inode) überprüfen, die wie folgt angezeigt wird:
stat -L -c %i FilePath
Ihr Scheck lautet jetzt:
if [ $(stat -L -c %i "/usr/bin/app.sh") == $(stat -L -c %i "$0") ] ...
Dies funktioniert unabhängig von etwaigen Links im Verzeichnispfad oder sogar einem symbolischen oder Hardlink zur Datei selbst.
Um ganz genau zu sein (danke an @ilkkachu für den Hinweis), ist es sehr unwahrscheinlich, dass zwei verschiedene Dateien mit demselben Namen denselben Inode auf zwei verschiedenen Dateisystemen haben. Um dies zu vermeiden, schließen Sie die Gerätenummer in den Vergleich ein:
if [ $(stat -L -c %d:%i "/usr/bin/app.sh") == $(stat -L -c %d:%i "$0") ] ...
Antwort2
readlink -f /path/to/whatever
teilt Ihnen den kanonischen Pfad mit (der /usr/bin/app.sh
in Ihrem Beispiel der Fall sein wird).
Ausdie Manpage:
kanonisieren, indem jedem Symlink in jeder Komponente des angegebenen Namens rekursiv gefolgt wird; alle Komponenten außer der letzten müssen vorhanden sein