Entweder ist das, was ich hier frage, extrem unorthodox / unkonventionell / riskant, oder meine Google-Fu-Kenntnisse sind einfach nicht ausreichend für Schnupftabak ...
Gibt es in einem bash
Shell-Skript eine einfache Möglichkeit, festzustellen, ob es von einem anderen Shell-Skript stammt oder von selbst ausgeführt wird? Mit anderen Worten, ist es möglich, zwischen den folgenden beiden Verhaltensweisen zu unterscheiden?
# from another shell script
source myScript.sh
# from command prompt, or another shell script
./myScript.sh
Ich überlege, ein Shell-Skript wie ein Dienstprogramm zu erstellen, das bash
Funktionen enthält, die bei der Beschaffung verfügbar gemacht werden können. Wenn dieses Skript von selbst ausgeführt wird, möchte ich, dass es bestimmte Vorgänge ausführt, die auch auf den definierten Funktionen basieren. Gibt es eine Art Umgebungsvariable, auf die dieses Shell-Skript zugreifen kann, z
some_function() {
# ...
}
if [ -z "$IS_SOURCED" ]; then
some_function;
fi
Am liebsten suche ich eine Lösung, bei der das Aufruferskript keine Flag-Variablen setzen muss.
edit : Ich kenne den Unterschied zwischen dem Sourcing und dem Ausführen des Skripts. Ich versuche hier herauszufinden, ob es möglich ist , den Unterschied im verwendeten Skript zu erkennen (auf beide Arten).
quelle
.
Befehl, sondern nach der Feststellung, ob ein Skript stammt oder normal ausgeführt wird (dh in einer Subshell).Antworten:
Ja - die Variable $ 0 gibt den Namen des Skripts an, wie es ausgeführt wurde:
Welches läuft wie:
Das bedeutet nicht, dass Sie eine Quelle einer interaktiven Shell sind, aber Sie bekommen diese Idee (hoffe ich).
Aktualisiert, um BASH_SOURCE einzuschließen - danke hjk
quelle
Die Kombination der Antwort von @ DarkHeart mit der Umgebungsvariablen
BASH_SOURCE
scheint den Trick zu machen:edit Scheint noch einfacher zu sein, wenn ich nur die Anzahl der Elemente im
BASH_SOURCE
Array zähle :quelle
Ich habe gerade die gleiche Art von Bibliotheksskript erstellt, die ähnlich wie BusyBox funktioniert. Darin benutze ich die folgende Funktion, um zu testen, ob es bezogen wird ...
Das von Bash gepflegte FUNCNAME-Array ist im Wesentlichen ein Funktionsaufrufstapel.
$FUNCNAME
(oder${FUNCNAME[0]}
) ist der Name der aktuell ausgeführten Funktion.${FUNCNAME[1]}
ist der Name der aufgerufenen Funktion und so weiter.Das oberste Element ist ein spezieller Wert für das Skript. Es wird enthalten ...
Die obige Funktion funktioniert eigentlich nur, wenn sie auf der Skriptebene aufgerufen wird (was alles ist, was ich brauche). Ein Aufruf aus einer anderen Funktion heraus würde fehlschlagen, da die Array-Artikelnummer falsch wäre. Damit es überall funktioniert, müssen Sie den oberen Bereich des Stapels finden und diesen Wert testen, was komplizierter ist.
Wenn Sie das brauchen, können Sie die Array-Artikelnummer der "Oberseite des Stapels" mit ...
${#FUNCNAME[@]}
ist die Anzahl der Elemente im Array. Als nullbasiertes Array subtrahieren wir 1, um die letzte Artikelnummer zu erhalten.Diese drei Funktionen werden zusammen verwendet, um eine Funktionsstapel-Ablaufverfolgung zu erstellen, die der von Python ähnelt, und sie geben Ihnen möglicherweise eine bessere Vorstellung davon, wie dies alles funktioniert ...
Beachten Sie, dass FUNCNAME, BASH_SOURCE und BASH_LINENO drei von bash verwaltete Arrays sind, als ob sie ein dreidimensionales Array wären.
quelle
Ich möchte nur hinzufügen, dass das Zählen des Arrays unzuverlässig erscheint, und man sollte wahrscheinlich nicht annehmen, dass
source
es verwendet wurde, da die Verwendung eines Punkts (.
) ebenfalls sehr häufig ist (und demsource
Schlüsselwort vorausgeht ).Zum Beispiel für ein
sourced.sh
Skript, das nur Folgendes enthältecho $0
:Die vorgeschlagenen Vergleichslösungen funktionieren besser.
quelle
Eine Möglichkeit, die auch bei der Beschaffung aus einer interaktiven Shell funktioniert :
Die
BASH_LINENO
Variable ist auch ein Array mit allen Zeilen, in denen die aufrufende Funktion ausgeführt wurde. Es ist Null, wenn Sie das Skript direkt aufrufen, oder eine Ganzzahl, die einer Zeilennummer entspricht.Die Variable BASH_ * docs
quelle