Antworten:
Für Ihr spezifisches Skript funktioniert jeder Weg, außer dass ./script.sh
die Ausführung und lesbare Bits bash script.sh
erforderlich sind , während nur lesbare Bits erforderlich sind.
Der Grund für den Unterschied in der Berechtigungsanforderung liegt darin, wie das Programm geladen wird, das Ihr Skript interpretiert:
./script.sh
Lässt Ihre Shell die Datei so ausführen, als ob sie eine reguläre ausführbare Datei wäre.Die Shell teilt sich selbst mit und verwendet einen Systemaufruf (z. B. execve
), damit das Betriebssystem die Datei im gegabelten Prozess ausführt. Das Betriebssystem überprüft die Dateiberechtigungen (daher muss das Ausführungsbit gesetzt sein) und leitet die Anforderung an den Programmlader weiter , der die Datei ansieht und festlegt, wie sie ausgeführt werden soll. Unter Linux beginnen kompilierte ausführbare Dateien mit einer magischen ELF- Nummer, während Skripte mit einem #!
( Hash ) beginnen. Ein Hashbang-Header bedeutet, dass die Datei ein Skript ist und von dem Programm interpretiert werden muss, das nach dem Hashbang angegeben ist. Dadurch kann ein Skript selbst dem System mitteilen, wie es das Skript interpretiert.
Mit Ihrem Skript wird der Programmlader ausgeführt /bin/bash
und ./script.sh
als Befehlszeilenargument übergeben.
bash script.sh
Lässt Ihre Shell als Befehlszeilenargument laufen bash
und übergebenscript.sh
Das Betriebssystem wird also geladen bash
(wird nicht einmal angezeigt script.sh
, da es sich nur um ein Befehlszeilenargument handelt). Der erstellte bash
Prozess interpretiert dann das, script.sh
weil es als Befehlszeilenargument übergeben wird. Da script.sh
nur bash
als reguläre Datei gelesen wird , ist das Ausführungsbit nicht erforderlich.
Ich empfehle jedoch die Verwendung ./script.sh
, da Sie möglicherweise nicht wissen, welchen Interpreter das Skript benötigt. Lassen Sie den Programmlader das für Sie bestimmen.
. ./script.sh
nicht das Gleiche wie bash script.sh
(oder ./script.sh
. Betrachten Sie das Skript #!/usr/bin/python -V
<newline> print test
.
. script.sh
. Aber ich stimme den Leuten 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, wenn es exit
Befehle enthält und Sie es als Quelle verwenden, Sie abmelden könnte. Ein weniger ernstes Problem wäre, wenn das Skript eine ausführt cd
, da dies auch die übergeordnete (interaktive) Shell betreffen würde.
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
ausführen, können Sie mit herausfinden which bash
.
In Ihrem Beispiel macht das also keinen Unterschied. Ja, Sie müssen chmod +x script.sh
es direkt über ausführen können ./script.sh
.
/bin/bash
ist das erste bash
in deinem $PATH
.
#!/bin/bash
funktioniert nur, wenn es einen/bin/bash
./script.sh
.
Erstellen Sie eine Datei Delete_Self.sh wie folgt:
#!/bin/rm
echo I am still here!
Führen Sie dieses Skript aus, wie sh Delete_Self.sh
Sie sehen werden "Ich bin immer noch hier!" hallte zurück.
Machen Sie es ausführbar und führen Sie es so ./Delete_Self.sh
aus, wie Sie sehen, dass nichts zurückgesendet wird, während die Datei Delete_Self.sh
selbst weg ist.
Der Unterschied ist also, dass:
bash script.sh
ignoriert das #! line, da bash als Programm zum Ausführen von script.sh angegeben ist../script.sh
wird das # lesen! Zeile, um das auszuführende Programm zu bestimmen script.sh
.Zusätzlich zu den anderen Antworten ist es nützlich , den Unterschied zwischen dem Ausführen eines Skripts über ./script.sh
(i) und dem Ausführen von Quelle ./script.sh
(ii) zu kennen. - Die Version (i) erstellt eine neue Shell, in der der Befehl ausgeführt werden kann, während (ii) sie in der ausführt Aktuelle Shell - Dies kann obligatorisch sein, 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
NB Eine andere Alternative, auf source
die Sie möglicherweise stoßen, ist das .
eingebaute, dh
. activate my_env