Was ist der Unterschied zwischen dem Ausführen von “ bash script.sh ” und “ ./script .sh ”?

Wenn script.sh nur etwas Typisches wie

#!/bin/bash echo "Hello World!" 

ist, gibt es eine bevorzugte Weg, um das Skript auszuführen? Ich denke, Sie müssen es zuerst ändern, damit es ausführbar wird?

Antwort

Für Ihr spezifisches Skript funktioniert es in beiden Fällen, außer dass ./script.sh Ausführung und lesbare Bits erfordert, während bash script.sh nur lesbares Bit erfordert.


Der Grund von Der Unterschied zwischen den Berechtigungsanforderungen besteht darin, wie das Programm geladen wird, das Ihr Skript interpretiert:

  • ./script.sh lässt Ihre Shell die Datei so ausführen, als wäre sie ein reguläres Programm ausführbare Datei.

Die Shell teilt sich selbst und verwendet einen Systemaufruf (z. B. execve), damit das Betriebssystem die Datei im gegabelten Prozess ausführt. Das Betriebssystem überprüft die Berechtigungen der Datei (daher muss das Ausführungsbit gesetzt werden) und leitet die Anforderung an den Programmlader weiter, der die Datei betrachtet und bestimmt, wie es ausgeführt werden soll. Unter Linux kompilierte ausführbare Dateien beginnen mit einer magischen Zahl ELF , während Skripte mit einer #! ( Hashbang ). Ein Hashbang-Header bedeutet, dass die Datei ein Skript ist und von dem Programm interpretiert werden muss, das nach dem Hashbang angegeben wird. Dies ermöglicht ein Skript selbst, um dem System mitzuteilen, wie das Skript zu interpretieren ist.

Mit Ihrem Skript führt der Programmlader /bin/bash aus und übergibt ./script.sh als Befehlszeilenargument.

  • bash script.sh lässt Ihre Shell bash ausführen und übergeben script.sh als Befehlszeilenargument

Das Betriebssystem lädt also (nicht einmal script.sh, da es sich nur um ein Befehlszeilenargument handelt). Der erstellte Prozess bash interpretiert dann den script.sh, weil er als Befehlszeilenargument übergeben wurde. Weil script.sh wird nur von bash als reguläre Datei gelesen, das Ausführungsbit ist nicht erforderlich.


Ich empfehle die Verwendung von ./script.sh, da Sie möglicherweise nicht wissen, welchen Interpreter das Skript benötigt. Lassen Sie den Programmlader dies für Sie bestimmen.

Kommentare

  • Wenn das ausführbare Bit nicht gesetzt ist, können Sie das Skript auch ausführen, indem Sie " ausführen ./script.sh"
  • @Dog Sie haben Recht. Der Punkt ist eine Verknüpfung für den integrierten Befehl ' source ' Daher wird nur das lesbare Bit benötigt.
  • @Dogeatcatworld Während dies zutrifft, ist das Ausführen von . ./script.sh nicht dasselbe Ding wie (oder ./script.sh. Betrachten Sie das Skript #!/usr/bin/python -V < newline > print test.
  • Beachten Sie, dass die Beschaffung eines Skripts zu einer Kontamination der interaktiven Sitzung führen kann. Sollte ein Skript beispielsweise die Umgebungsvariable PATH ändern, wirkt sich diese Änderung auf Befehle aus, die nach der Quelle ausgeführt werden. Dieser Ansatz sollte wirklich für Situationen reserviert sein, in denen Sie von den Nebenwirkungen abhängen (Umgebungs-Setup-Skripte und dergleichen). In anderen Situationen, in denen Sie ' die Berechtigungen nicht ändern können, ist es am sichersten, den Befehl in der Shebang-Zeile gefolgt vom Skriptnamen auszuführen.
  • Beachten Sie dies Wenn Sie ein Skript im aktuellen Verzeichnis als Quelle verwenden, müssen Sie nicht ./ verwenden. Sagen Sie einfach . script.sh. Ich stimme jedoch den Personen zu, die davon abraten, den Befehl . für Skripte zu verwenden, die nicht auf diese Weise aufgerufen werden sollten. Ich bin überrascht, dass niemand erwähnt hat, dass das Skript Sie abmelden könnte, wenn es exit -Befehle enthält und Sie es als Quelle verwenden. Ein weniger schwerwiegendes Problem wäre, wenn das Skript eine cd ausführt, da dies auch die übergeordnete (interaktive) Shell betreffen würde.

Antwort

bash script.sh ruft das Skript direkt mit der Bash auf.
./script.sh verwendet den shebang #!/bin/bash, um zu bestimmen, wie ausgeführt werden soll.

Wenn Sie wirklich wissen möchten, welche Binärdatei ausgeführt wird, wenn Sie eine bash script.sh können Sie mit which bash herausfinden.

In Ihrem Beispiel macht es also keinen Unterschied. Ja, Sie müssen chmod +x script.sh ausführen, um es direkt über ./script.sh ausführen zu können.

Kommentare

  • Nun, es macht keinen Unterschied, ob /bin/bash die erste bash in Ihrem $PATH.
  • Sie ' haben Recht. Und der shebang #!/bin/bash funktioniert nur, wenn auf meinem ein /bin/bash
  • Bash (Version 4.2.37) vorhanden ist Das System führt Skripte auch ohne gesetztes Ausführungsbit aus. Warum ist das Ausführungsbit erforderlich?
  • Ja, das Ausführungsbit wird nur durch Aufrufen über ./script.sh benötigt.

Antwort

Erstellen Sie eine Datei Delete_Self.sh wie folgt:

 #!/bin/rm echo I am still here! 

Führen Sie diese aus Skript als sh Delete_Self.sh Sie werden sehen „Ich bin immer noch hier!“ Echo zurück.

Machen Sie es ausführbar und führen Sie es als ./Delete_Self.sh aus. Sie werden sehen, dass nichts zurückgesendet wird, während die Datei Delete_Self.sh selbst ist weg.

Der Unterschied besteht also darin, dass:

  • bash script.sh das # ignoriert! Zeile, da bash als Programm zum Ausführen von script.sh angegeben ist.
  • ./script.sh liest das #! Zeile, um das Programm zu bestimmen, das ausgeführt werden soll script.sh.

Kommentare

  • +1 für das schöne Beispiel

Antwort

Zusätzlich zu den anderen Antworten sollten Sie den Unterschied zwischen dem Ausführen eines Skripts über ./script.sh (i) und source ./script.sh (ii) sind nützlich – Die Version (i) erstellt eine neue Shell, in der der Befehl ausgeführt werden kann. wohingegen (ii) es in der aktuellen Shell ausführt – was obligatorisch sein kann, wenn die ausführbare Datei Umgebungsvariablen ändert, die nach dem Beenden der ausführbaren Datei beibehalten werden müssen. Um beispielsweise eine Python-Conda-Umgebung zu aktivieren, muss Folgendes verwendet werden:

source activate my_env 

N.B. Eine andere Alternative zu source, auf die Sie möglicherweise stoßen, ist das integrierte ., dh

. activate my_env 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.