GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum ist es besser, „#!/usr/bin/env Name“ statt „#!/path/to/name“ als Shebang zu verwenden?

Mir ist aufgefallen, dass einige Skripte, die ich von anderen erworben habe, den Shebang #!/path/to/NAME haben während andere (die dasselbe Tool verwenden, NAME) den Shebang #!/usr/bin/env NAME haben .

Beide scheinen richtig zu funktionieren. In Tutorials (zum Beispiel zu Python) scheint es einen Vorschlag zu geben, dass letzteres besser ist. Aber ich verstehe nicht ganz, warum das so ist.

Mir ist klar, dass, um letzteres zu verwenden, NAME im PATH stehen muss, während das erste Shebang diese Einschränkung nicht hat.

Außerdem scheint (mir) der erste der bessere Shebang zu sein, da er genau angibt, wo sich NAME befindet. Wenn also in diesem Fall mehrere Versionen von NAME vorhanden sind (z. B. /usr/bin/NAME, /usr/local/bin/NAME), gibt der erste Fall an, welche verwendet werden soll.

Meine Frage ist, warum wird der erste Shebang dem zweiten vorgezogen?

Akzeptierte Antwort:

Objektive Kriterien/Anforderungen:

Bei der Entscheidung, ob ein Absolutwert verwendet werden soll oder logisch (/usr/bin/env ) Pfad zu einem Dolmetscher in einem She-Bang, gibt es (2) Schlüsselüberlegungen:

a) Der Dolmetscher kann auf dem Zielsystem gefunden werden

b) Die korrekte Version von Dolmetscher kann auf dem Zielsystem gefunden werden

Wenn wir EINVERSTANDEN sind dass „b) ” wünschenswert ist, da stimmen wir auch zu :

c) Es ist vorzuziehen, dass unsere Skripte fehlschlagen anstatt mit einer falschen Interpreterversion auszuführen und möglicherweise inkonsistente Ergebnisse zu erzielen.

Wenn wir NICHT EINVERSTANDEN sind dass „b) ” zählt, dann reicht jeder gefundene Dolmetscher aus.

Testen:

Seit der Verwendung eines logischen path- /usr/bin/env to the interpreter in the she-bang ist die am besten erweiterbare Lösung, die es ermöglicht, dasselbe Skript erfolgreich auf Zielhosts mit unterschiedlichen Pfaden zu demselben Interpreter auszuführen. Wir werden es testen - aufgrund seiner Popularität mit Python - um zu sehen, ob es passt unsere Kriterien.

  1. Tut /usr/bin/env an einem vorhersehbaren, konsistenten Ort auf POPULAR leben (nicht „alle ") Betriebssysteme? Ja :
  • RHEL 7.5
  • Ubuntu 18.04
  • Raspbian 10 („Buster“)
  • OSX 10.15.02
  1. Below Python-Skript, das sowohl innerhalb als auch außerhalb von virtuellen Umschlägen ausgeführt wird (Pipenv verwendet) während Tests:
    #!/usr/bin/env pythonX.x
    import sys
    print(sys.version)
    print('Hello, world!')
    
  2. Der She-Bang im Skript wurde durch die gewünschte Python-Versionsnummer umgeschaltet (alle auf demselben Host installiert):
  • #!/usr/bin/env python2
  • #!/usr/bin/env python2.7
  • #!/usr/bin/env python3
  • #!/usr/bin/env python3.5
  • #!/usr/bin/env python3.6
  • #!/usr/bin/env python3.7
  1. Erwartete Ergebnisse:das print(sys.version) =env pythonX.x . Jedes Mal ./test1.py mit einer anderen installierten Python-Version ausgeführt wurde, wurde die im She-Bang angegebene korrekte Version gedruckt.

  2. Testhinweise:

  • Die Tests waren ausschließlich auf Python beschränkt
  • Perl:Wie Python - MUSS leben in /usr/bin laut FHS
  • Ich habe nicht jede mögliche Kombination auf jeder möglichen Anzahl von Linuxy/Unixy-Betriebssystemen und Versionen jedes Betriebssystems ausprobiert.
Verwandt:Linux – Abrufen von Funktionen des CD/DVD-Laufwerks, wenn Wodim-Geräte nicht funktionieren?

Schlussfolgerung:

Obwohl es WAHR ist, dass #!/usr/bin/env python die erste Version von Python verwendet, die es im Pfad des Benutzers findet, können wir dieses Verhalten moderieren, indem wir eine Versionsnummer wie #!/usr/bin/env pythonX.x angeben . Tatsächlich ist es Entwicklern egal, welcher Interpreter „zuerst“ gefunden wird „Alles, was ihnen wichtig ist, ist, dass ihr Code mit dem angegebenen Interpreter ausgeführt wird, von dem sie wissen, dass er mit ihrem Code kompatibel ist, um konsistente Ergebnisse zu gewährleisten – wo auch immer dieser im Dateisystem vorhanden sein mag

In Bezug auf Portabilität/Flexibilität ist die Verwendung eines logischen /usr/bin/env – statt absolut path erfüllt nicht nur die Anforderungen a), b) &c) aus meinen Tests mit verschiedenen Versionen von Python , hat aber auch den Vorteil, dass die Fuzzy-Logik den gleichen Versionsinterpreter findet, selbst wenn sie auf verschiedenen Betriebssystemen auf unterschiedlichen Pfaden leben. Und zwar MEIST Distributionen respektieren die FHS, nicht alle.

Wo also ein Skript FEHLER wird wenn binär in verschiedenen absoluten lebt Pfad dann in Shebang angegeben, das gleiche Skript mit einem logischen Pfad SUCCEEDS da es so lange läuft, bis es eine Übereinstimmung findet, wodurch eine größere Zuverlässigkeit und Erweiterbarkeit über Plattformen hinweg geboten wird.


Linux
  1. /usr/bin vs. /usr/local/bin Unter Linux?

  2. Gibt es einen Grund, einen Shebang zu haben, der auf /bin/sh statt auf /bin/bash zeigt?

  3. Linux – Zusammenführen von /usr/bin und /usr/sbin in /bin (gnu/linux)?

  4. Installieren Sie Binärdateien in /bin, /sbin, /usr/bin und /usr/sbin, Interaktionen mit --prefix und DESTDIR

  5. Was bedeuten /usr/sbin, /usr/local/sbin und /usr/local/bin?

Wann sollte ich /dev/shm/ verwenden und wann sollte ich /tmp/?

Wann muss ich #!/bin/bash und wann #!/bin/sh verwenden?

Warum andere Dinge als /home auf eine separate Partition legen?

Unterschied zwischen /bin und /usr/bin

Warum haben die Verzeichnisse /home, /usr, /var usw. alle dieselbe Inode-Nummer (2)?

Warum sind < oder > erforderlich, um /dev/tcp