Antworten:
Wenn du benutzt
sh ./<script>.run
/bin/sh
(normalerweise eine Bourne-Shell) wird zum Ausführen des Skripts verwendet. Dies funktioniert natürlich nur, wenn das Skript für die Bourne-Shell geschrieben wurde. Manchmal erfordern Shell-Skripte für Linux Bash anstelle der Bourne-Shell, sodass dies möglicherweise nicht funktioniert, selbst wenn es sich um ein Shell-Skript handelt.
Wenn du benutzt
./<script>.run
Der Kernel überprüft die Shebang-Zeile , um herauszufinden, mit welchem Programm das Programm ausgeführt werden soll. Dies funktioniert also auch, wenn es sich um ein Bash-, Perl-, Python- oder ein anderes Skript handelt.
Daher ist dies normalerweise die bevorzugte Methode zum Ausführen eines Skripts.
Solange es sich um ein sh
(Dash- oder gleichwertiges) Shell-Skript handelt, gibt es keinen äußerlichen Unterschied.
Das Problem ist .run
nicht garantiert, dass dies der Fall ist. Es könnte binär sein. Es könnte Bash oder Python oder PHP oder was auch immer sein; Sie haben alle ein Shell-Skript-Hash-Bang. Wenn Sie es blindlings durchsetzen sh
, wer weiß, was passieren könnte? Es wird wahrscheinlich ein Fehler auftreten, aber es könnte versehentlich schädlichen Code ausführen, bevor es soweit ist.
Indem Sie es chmod
dingen (um das Ausführungsberechtigungsbit zu aktivieren) und dann ausführen ./script.run
, geben Sie ihm die bestmögliche Ausführungsmöglichkeit. Wenn es sich um ein Shell-Skript handelt, wird sein Hash-Bang ordnungsgemäß analysiert, und wenn es sich um eine ausführbare Binärdatei handelt, wird es nur nativ ausgeführt.
Die beiden Methoden können oft gleich wirken, sind aber sehr unterschiedlich.
sh ./script
Führt den sh
Befehl mit einem Argument aus ./script
, das das angegebene Skript ausführt. Auch wenn das Skript eigentlich kein sh
Skript ist (fehlerhaft)
./script
Führt die angegebene Datei aus. Dies geschieht, indem nach der Zeile "shebang" gesucht wird, um zu bestimmen, welcher Befehl ausgeführt werden soll. Wenn nicht angegeben, wird verwendet sh
(diese beiden Methoden verhalten sich manchmal gleich), häufig wird jedoch ein anderer Interpreter angegeben.
Zum Beispiel, wenn filename
Folgendes enthalten ist:
#!/usr/bin/python
print "This is a Python script!"
..dann sind die beiden Befehle sehr unterschiedlich:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Wenn es keine Shebang-Linie gibt, sind die beiden gleich:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Ein wichtiger Unterschied ist, ob Ihre Hashbang-Linie Parameter enthält. Zum Beispiel, wenn das Skript mit beginnt
#!/bin/bash -e
... und Sie führen es extern mit sh
oder aus bash
. Diese Zeile wird als Kommentar interpretiert und ignoriert, sodass der -e
Parameter (Exit bei Fehler) nicht verarbeitet wird. Also, angesichts des folgenden Skripts:
#!/bin/bash -e
echo Hello
false
echo goodbye
Die Ausgabe für ./script
wird nur "Hallo" sein, aber die Ausgabe für sh script
wird Hello
gefolgt von goodbye
, was wahrscheinlich nicht beabsichtigt war.
Dies ist übrigens der Grund, warum Sie immer eine separate set -e
Anweisung verwenden sollten (es ist sowieso eine gute Idee - meistens möchten Sie nicht, dass ein Problem in der Mitte des Skripts ignoriert wird).