Ampliando la respuesta (actualmente aceptada) de redneb...
TL;RD Necesita obtener una secuencia de comandos sin argumentos posicionales dentro de otra secuencia de comandos ? prueba function DoSource() { source test.sh ; } ; DoSource
en lugar de solo source test.sh
.
source
ing un script sin argumentos dentro de otro script
El extracto de Bash manual en la pregunta muestra los detalles de cómo se asignan los parámetros posicionales al script de origen. En particular, si el comando fuente no especifica ningún argumento , se le asignan las del entorno llamante.
Una consecuencia es que puede ser problemático para source
un script que no pasa argumentos dentro de otra secuencia de comandos. Por ejemplo, usemos el ejemplo de redneb como test.sh
:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
obtenido dentro de otra secuencia de comandos userScript.sh
, que es, por ejemplo, el de una sola línea:
source test.sh
Al ejecutar un ejemplo como el anterior:
$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
test.sh
hereda userScript.sh
argumentos posicionales... que ahora no es lo que quiero (si lo hubiera hecho, podría haber usado source test.sh "[email protected]"
).
Descubrí que lo siguiente es una solución útil:encapsule el comando fuente en una función Bash. El nuevo userScript.sh
parece:
function DoSource() { source test.sh ; }
DoSource
informes:
$ bash userScript.sh a 'b c'
I was given 0 argument(s):
Tenga en cuenta que especificar un argumento vacío (source test.sh ''
) no es equivalente, ya que el argumento vacío se pasaría a test.sh
.
Si también se espera obtener el script de abastecimiento
Si userScript.sh
se supone que debe ser fuente, entonces uno probablemente no quiera dejar DoSource()
alrededor. En ese caso, la solución simple es la autodestrucción:
function _userScript_sh_DoSource() { source test.sh ; unset "$FUNCNAME" ; }
_userScript_sh_DoSource
para uso de una sola vez (el nombre de la función se ha elegido para reducir la posibilidad de conflictos de nombres); o un unset _userScript_sh_DoSource
el comando puede estar ubicado después de _userScript_sh_DoSource
ya no es necesario.
Variante flexible para múltiples usos
Una variante más compleja de DoSource()
:
function DoSource() { local ScriptName="$1" ; shift ; source "$ScriptName" ; }
DoSource test1.sh
DoSource test1.sh "[email protected]"
DoSource test2.sh
se puede usar como un reemplazo "directo" para source
, con la única diferencia de que cuando no se especifica un argumento posicional para que se obtenga el script, source
los hereda, mientras que DoSource
no usa ninguno. Sin embargo, tenga en cuenta que DoSource
es una función y como tal se comporta de manera diferente a source
en otros aspectos (por ejemplo, llamada de pila, FUNCNAME
, ...).
Crea un archivo test.sh
con los siguientes contenidos:
echo "I was given $# argument(s):"
printf "%s\n" "[email protected]"
y luego obténgalo desde una sesión de shell interactiva:
$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
por lo que accede a los argumentos como lo haría en un script bash regular, con [email protected]
o $1
, $2
, $3
, etc
A modo de comparación, ejecútelo como un script normal:
$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c