Espandendo la risposta (attualmente accettata) di redneb...
TL;DR È necessario generare uno script senza argomenti posizionali all'interno di un altro script ? prova function DoSource() { source test.sh ; } ; DoSource
invece di solo source test.sh
.
source
ing uno script senza argomenti all'interno di un altro script
L'estratto da Bash manuale nella domanda mostra i dettagli di come i parametri posizionali sono assegnati allo script di origine. In particolare, se il comando source non specifica alcun argomento , viene assegnato a quelli dell'ambiente chiamante.
Una conseguenza è che potrebbe essere problematico source
uno script che non passa argomenti all'interno di un altro script. Ad esempio, usiamo redneb example come test.sh
:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
originato all'interno di un altro script userScript.sh
, che è ad es. la battuta:
source test.sh
Quando si esegue un esempio come sopra:
$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
test.sh
eredita userScript.sh
argomenti posizionali... che ora non è quello che voglio (se l'avessi fatto, avrei potuto usare source test.sh "[email protected]"
).
Ho trovato la seguente soluzione utile:incapsulare il comando source in una funzione Bash. Il nuovo userScript.sh
sembra:
function DoSource() { source test.sh ; }
DoSource
rapporti:
$ bash userScript.sh a 'b c'
I was given 0 argument(s):
Nota che specificando un argomento vuoto (source test.sh ''
) non è equivalente, poiché l'argomento vuoto verrebbe passato a test.sh
.
Se si prevede che anche lo script di sourcing venga fornito
Se userScript.sh
stesso dovrebbe essere originato, quindi probabilmente non si vuole lasciare DoSource()
intorno a. In tal caso, la soluzione semplice è l'autodistruzione:
function _userScript_sh_DoSource() { source test.sh ; unset "$FUNCNAME" ; }
_userScript_sh_DoSource
per un solo utilizzo (il nome della funzione è stato scelto per ridurre la possibilità di conflitti di nome); o un unset _userScript_sh_DoSource
il comando può essere posizionato dopo _userScript_sh_DoSource
non è più necessario.
Variante flessibile per uso multiplo
Una variante più complessa di DoSource()
:
function DoSource() { local ScriptName="$1" ; shift ; source "$ScriptName" ; }
DoSource test1.sh
DoSource test1.sh "[email protected]"
DoSource test2.sh
può essere utilizzato come sostituto "drop-in" di source
, con l'unica differenza che quando non viene specificato alcun argomento posizionale per lo script di cui deve essere originato, source
li eredita, mentre DoSource
usa nessuno. Nota comunque che DoSource
è una funzione e come tale si comporta diversamente da source
in altri aspetti (ad es. chiamata allo stack, FUNCNAME
, ...).
Crea un file test.sh
con i seguenti contenuti:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
e quindi recuperarlo da una sessione shell interattiva:
$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
quindi accedi agli argomenti proprio come faresti in un normale script bash, con [email protected]
o $1
, $2
, $3
, ecc.
Per confronto, eseguilo come uno script normale:
$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c