Rozšíření o (aktuálně přijatou) odpověď od redneb...
TL;DR Potřebujete zdrojový skript bez pozičních argumentů v rámci jiného skriptu ? zkuste function DoSource() { source test.sh ; } ; DoSource
místo pouze source test.sh
.
source
ing skriptu bez argumentů v jiném skriptu
Výňatek z Bash manuál v otázce ukazuje podrobnosti o tom, jak jsou poziční parametry přiřazeny zdrojovému skriptu. Zejména pokud příkaz source neuvádí žádný argument , jsou mu přiřazeny ty z volajícího prostředí.
Důsledkem je, že source
může být problematické skript nepředávající žádné argumenty v jiném skriptu. Použijme například redneb jako test.sh
:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
pochází z jiného skriptu userScript.sh
, což je např. jedna vložka:
source test.sh
Při spuštění příkladu jako výše:
$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
test.sh
zdědí userScript.sh
poziční argumenty... což teď není to, co chci (kdybych to udělal, mohl jsem použít source test.sh "[email protected]"
).
Zjistil jsem, že následující je užitečné řešení:zapouzdřit zdrojový příkaz do funkce Bash. Nový userScript.sh
vypadá takto:
function DoSource() { source test.sh ; }
DoSource
zprávy:
$ bash userScript.sh a 'b c'
I was given 0 argument(s):
Všimněte si, že zadáním prázdného argumentu (source test.sh ''
) není ekvivalentní, protože prázdný argument by byl předán do test.sh
.
Pokud se očekává, že zdrojový skript bude také zdrojový
Pokud userScript.sh
sám o sobě má být zdrojový, pak pravděpodobně nechcete opustit DoSource()
kolem. V tom případě je jednoduchým řešením sebezničení:
function _userScript_sh_DoSource() { source test.sh ; unset "$FUNCNAME" ; }
_userScript_sh_DoSource
pro jednorázové použití (název funkce byl zvolen, aby se snížila možnost konfliktů názvů); nebo unset _userScript_sh_DoSource
příkaz může být umístěn za _userScript_sh_DoSource
již není potřeba.
Flexibilní varianta pro více použití
Složitější varianta DoSource()
:
function DoSource() { local ScriptName="$1" ; shift ; source "$ScriptName" ; }
DoSource test1.sh
DoSource test1.sh "[email protected]"
DoSource test2.sh
lze použít jako "drop-in" náhradu za source
, s jediným rozdílem, že když není pro zdrojový skript zadán žádný argument pozice, source
zdědí je, zatímco DoSource
nepoužívá žádné. Všimněte si však, že DoSource
je funkce a jako taková se chová odlišně od source
v jiných aspektech (např. volání zásobníku, FUNCNAME
, ...).
Vytvořte soubor test.sh
s následujícím obsahem:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
a poté jej získejte z interaktivní relace shellu:
$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
takže k argumentům přistupujete stejně jako v běžném bash skriptu s [email protected]
nebo $1
, $2
, $3
, atd.
Pro srovnání jej spusťte jako běžný skript:
$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c