Erweiterung der (derzeit akzeptierten) Antwort von Redneb ...
TL;DR Sie müssen ein Skript ohne Positionsargumente innerhalb eines anderen Skripts beziehen ? versuchen Sie es mit function DoSource() { source test.sh ; } ; DoSource
statt nur source test.sh
.
source
Ein Skript ohne Argumente in ein anderes Skript einfügen
Der Auszug aus Bash Handbuch in der Frage zeigt die Details, wie die Positionsparameter dem Quellskript zugewiesen werden. Insbesondere wenn der Quellbefehl kein Argument angibt , es werden die aus der aufrufenden Umgebung zugewiesen.
Eine Folge davon ist, dass es zu Problemen mit source
kommen kann ein Skript, das keine Argumente übergibt innerhalb eines anderen Skripts. Verwenden wir zum Beispiel redneb example als test.sh
:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
aus einem anderen Skript stammen userScript.sh
, das ist z. der Einzeiler:
source test.sh
Wenn Sie ein Beispiel wie oben ausführen:
$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
test.sh
erbt userScript.sh
Positionsargumente ... was ich jetzt nicht will (wenn ich es getan hätte, hätte ich source test.sh "[email protected]"
verwenden können ).
Ich habe festgestellt, dass Folgendes eine nützliche Problemumgehung ist:Kapseln Sie den Quellbefehl in eine Bash-Funktion. Das neue userScript.sh
sieht so aus:
function DoSource() { source test.sh ; }
DoSource
Berichte:
$ bash userScript.sh a 'b c'
I was given 0 argument(s):
Beachten Sie, dass die Angabe eines leeren Arguments (source test.sh ''
) ist nicht äquivalent, da das leere Argument an test.sh
übergeben würde .
Wenn das Beschaffungsskript auch beschafft werden soll
Wenn userScript.sh
selbst bezogen werden soll, dann will man DoSource()
wohl nicht verlassen um. In diesem Fall ist die einfache Lösung die Selbstzerstörung:
function _userScript_sh_DoSource() { source test.sh ; unset "$FUNCNAME" ; }
_userScript_sh_DoSource
zur einmaligen Verwendung (der Funktionsname wurde gewählt, um die Wahrscheinlichkeit von Namenskonflikten zu verringern); oder ein unset _userScript_sh_DoSource
Befehl kann nach _userScript_sh_DoSource
platziert werden wird nicht mehr benötigt.
Flexible Variante zur Mehrfachverwendung
Eine komplexere Variante von DoSource()
:
function DoSource() { local ScriptName="$1" ; shift ; source "$ScriptName" ; }
DoSource test1.sh
DoSource test1.sh "[email protected]"
DoSource test2.sh
kann als "drop-in"-Ersatz für source
verwendet werden , mit dem einzigen Unterschied, dass, wenn kein Positionsargument für das zu beziehende Skript angegeben ist, source
erbt sie, während DoSource
verwendet keine. Beachten Sie jedoch, dass DoSource
ist eine Funktion und verhält sich als solche anders als source
in anderen Aspekten (z. B. Stapelaufruf, FUNCNAME
, ...).
Erstellen Sie eine Datei test.sh
mit folgendem Inhalt:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
und beziehen Sie es dann aus einer interaktiven Shell-Sitzung:
$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
Sie greifen also auf die Argumente zu, wie Sie es in einem normalen Bash-Skript tun würden, mit [email protected]
oder $1
, $2
, $3
usw.
Führen Sie es zum Vergleich als reguläres Skript aus:
$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c