Welche Art von Weg in Shebang ist vorzuziehen?

20

In Skripten sollte in der ersten Zeile der Pfad zum Interpreter angegeben werden.
Auf verschiedenen Servern unter Linux, Unix oder BSD kann dieser Pfad jedoch unterschiedlich sein.

Was ist vorzuziehen?

#!/usr/bin/env bash 

oder

#!/bin/bash 
Roman Ivanov
quelle

Antworten:

22

Wenn Sie die vom System installierte Version eines bestimmten Interpreters verwenden möchten, der an einem Standardspeicherort installiert ist, verwenden Sie den direkten Pfad. Wenn Sie die Version des Interpreters verwenden möchten, die zuerst im Benutzer angezeigt wird $PATH, verwenden Sie #!/usr/bin/env ....

Der envBefehl ruft einen angegebenen Befehl auf, mit dem Sie Umgebungsvariablen festlegen oder deaktivieren können:

env FOO=BAR do-something
env DISPLAY=:0.0 xterm -ls &

Wenn Sie keine Umgebungsvariablen oder andere Optionen angeben, wird nur der genannte Befehl aufgerufen. (Es auf diese Weise zu benutzen ist wohl ein bisschen hacken.)

Der Zweck des Schreibens des Shebang als

#!/usr/bin/env interp

ist aufzurufen, was interpzuerst in erscheint $PATH.

Das heißt , Sie müssen nicht wissen, wenn das Skript zu schreiben, wo genau interpist (sagen wir, wenn es entweder in sein könnte /bin, /usr/binoder /usr/local/bin). Natürlich müssen Sie wissen , dass envist /usr/bin/env, aber das scheint ziemlich universell zu sein.

Der Vorteil ist, dass die Version des Interpreters aufgerufen wird, die zuerst im Benutzer angezeigt wird $PATH. Der Nachteil ist, dass es die Version des Interpreters aufruft, die zuerst im Benutzer angezeigt wird $PATH.

Nehmen wir zum Beispiel an, ich habe einen persönlichen Build von perlunter meinem Home-Verzeichnis as installiert $HOME/bin/perlund $HOME/binvorne auf meinem $PATH. Wenn ich ein Skript starte, dessen Wahnsinn ist

#!/usr/bin/env perl

dann wird es mit meiner selbst installierten perlausführbaren Datei ausgeführt - was möglicherweise nicht gut ist. Der Autor des Skripts hat es wahrscheinlich nicht mit dem neuesten Perl getestet, das ich vor einem Monat aus dem Quellcode erstellt habe.

Für so etwas wie Perl oder Bash , die in einer konsistenten Position installiert werden , auf den meisten Systemen (wahrscheinlich ist , /usr/bin/perlund /bin/bash, respectively), würde ich den direkten Weg zum Befehl verwenden. Für etwas Obskureres, das auf verschiedenen Systemen unterschiedlich installiert werden könnte, würde ich entweder den /usr/bin/envTrick verwenden oder ein Installationsprogramm schreiben, das die Shebang-Zeile anpasst, während das Skript installiert wird. (Früher musste ich das für meine Perl-Skripte tun.)

UPDATE: In dieser Antwort auf diese Frage auf der Unix- und Linux-Site habe ich ein bisschen mehr Details beschrieben .

Keith Thompson
quelle
Ich habe mich gerade mit Ruby befasst und festgestellt, dass die Konvention in Ruby aus Gründen der Portabilität mit [code] #! / Usr / bin / env ruby ​​[/ code] beginnen soll. Einige bemerkten, dass dies es schwierig macht, dem Ruby-Interpreter Befehlszeilenargumente wie '-w' zur Verfügung zu stellen, was auch für Perl ein Problem darstellen würde.
BGVAUGHAN
@bgvaughan Für Perl ist es heutzutage traditionell, nur das Skript zu verwenden #!/usr/bin/perlund dann use strict; use warnings;im Hauptteil des Skripts zu verwenden, anstatt #!/usr/bin/perl -w. Aber -That auf dem shebang sein.
Keith Thompson
Warum also nicht #! perl verwenden, wenn wir nur den ersten auf dem Weg haben wollen?
Ab dem
@wheredidthatnamecomefrom: Weil das nicht funktioniert. Die Behandlung der #!Linie wird nicht verwendet $PATH. Sie müssen den Pfad des Interpreters angeben. (Mir ist gerade klar geworden, dass dies zumindest auf meinem System ein relativer Pfad sein kann, aber das ist selten nützlich.)
Keith Thompson
6

Die beste Vorgehensweise ist folgende:

#!/usr/bin/env bash 
#!/usr/bin/env sh
#!/usr/bin/env python

Und so weiter...

Als Ubuntu anfing, dash zu benutzen, brachen einige Skripte. Es wurde darüber diskutiert. Die meisten Skripte wurden geschrieben, #!/bin/shwas ein Link zu / bin / bash war. Der Konsens ist folgender: Der Drehbuchautor ist für die Angabe des Interpreters verantwortlich. Wenn Ihr Skript daher immer mit BASH aufgerufen werden soll, geben Sie es in der Umgebung an. Dies erspart Ihnen das Erraten des Pfades, der auf verschiedenen Unix / Linux-Systemen unterschiedlich ist. Außerdem funktioniert es, wenn / bin / sh morgen eine Verknüpfung zu einer anderen Shell wie / bin / wthsh oder einem anderen Unsinn wird.


quelle
Die offensichtliche alternative Lösung für das Dash-Problem war das Schreiben #!/bin/bash. Ich bin damit einverstanden, dass der Drehbuchautor für die Angabe des Dolmetschers verantwortlich ist. Wenn Sie jedoch Bash benötigen, sagen Sie Bash nicht Sh
Martin Bonner unterstützt Monica
1

Zu Ihrer Information, es ist ein Wahnsinn #! , du brauchst das #. In dieser Zeile legen Sie fest, mit welchem ​​Interpreter das Skript ausgeführt werden soll.

Standardmäßig verlinkt Ubuntu /bin/shauf dash

Je nachdem, wie viel Sie über dash wissen möchten und warum dash für System- oder Deamon-Shells verwendet wird, sehen Sie:

cyberciti.biz dash

Ubuntu Dash Manpage

Bash ist die Standard-Shell, die von den meisten Linux-Benutzern verwendet wird und hat andere Funktionen als Dash. Ein für bash geschriebenes Skript wird möglicherweise nicht ordnungsgemäß ausgeführt, wenn es mit einem Bindestrich ausgeführt wird. Je komplexer das Skript ist, desto unwahrscheinlicher ist es, dass es ausgeführt wird.

Für Perl, Python usw. geschriebene Skripte werden mit /bin/shoder überhaupt nicht ausgeführt /bin/bash.

Wenn Sie also ein Skript schreiben, legen Sie fest, welcher Interpreter mit dem Shee-Bang verwendet werden soll

Die Auswahl der zu verwendenden Elemente erfolgt durch den Autor des Skripts, und eines ist nicht besser als das andere. Alle haben verschiedene Merkmale, Vor- und Nachteile.

Panther
quelle