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" "example@unixlinux.online"
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 "example@unixlinux.online" ).
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 "example@unixlinux.online"
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" "example@unixlinux.online"
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 example@unixlinux.online 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