Bash, desde la versión 4.3, febrero de 2014 (?), Tiene soporte explícito para variables de referencia o referencias de nombre (namerefs), más allá de "eval", con el mismo rendimiento beneficioso y efecto indirecto, y que puede ser más claro en sus scripts y también más difícil para "olvidar 'evaluar' y corregir este error":
declare [-aAfFgilnrtux] [-p] [name[=value] ...]
typeset [-aAfFgilnrtux] [-p] [name[=value] ...]
Declare variables and/or give them attributes
...
-n Give each name the nameref attribute, making it a name reference
to another variable. That other variable is defined by the value
of name. All references and assignments to name, except for⋅
changing the -n attribute itself, are performed on the variable
referenced by name's value. The -n attribute cannot be applied to
array variables.
...
When used in a function, declare and typeset make each name local,
as with the local command, unless the -g option is supplied...
y también:
PARÁMETROS
A la variable se le puede asignar el atributo nameref utilizando la opción -n para los comandos locales declare o local (consulte las descripciones de declare y local a continuación) para crear un nameref o una referencia a otra variable. Esto permite que las variables sean manipuladas indirectamente. Cada vez que se hace referencia a la variable nameref o se le asigna, la operación se realiza realmente en la variable especificada por el valor de la variable nameref. Un nameref se usa comúnmente dentro de las funciones de shell para referirse a una variable cuyo nombre se pasa como argumento a⋅ la función. Por ejemplo, si se pasa un nombre de variable a una función de shell como primer argumento, ejecutar
declare -n ref=$1
dentro de la función crea una variable nameref ref cuyo valor es el nombre de la variable pasado como primer argumento. Las referencias y asignaciones a ref se tratan como referencias y asignaciones a la variable cuyo nombre se pasó como $ 1. Si la variable de control en un bucle for tiene el atributo nameref, la lista de palabras puede ser una lista de variables de shell, y se establecerá una referencia de nombre para cada palabra en la lista, a su vez, cuando se ejecute el bucle. Las variables de matriz no pueden recibir el atributo -n. Sin embargo, las variables nameref pueden hacer referencia a variables de matriz y variables de matriz suscritas. Namerefs se puede ⋅ desarmar usando la opción -n para el desarmado incorporado. De lo contrario, si unset se ejecuta con el nombre de una variable nameref como argumento,
Por ejemplo ( EDIT 2 : (gracias, Ron), el espacio de nombres (prefijado) del nombre de la variable interna de la función, para minimizar los conflictos de variables externas, que finalmente deberían responder adecuadamente, el problema planteado en los comentarios de Karsten):
# $1 : string; your variable to contain the return value
function return_a_string () {
declare -n ret=$1
local MYLIB_return_a_string_message="The date is "
MYLIB_return_a_string_message+=$(date)
ret=$MYLIB_return_a_string_message
}
y probando este ejemplo:
$ return_a_string result; echo $result
The date is 20160817
Tenga en cuenta que el bash "declare" incorporado, cuando se usa en una función, hace que la variable declarada sea "local" por defecto, y "-n" también se puede usar con "local".
Prefiero distinguir las variables de "declaración importante" de las variables "locales aburridas", por lo que usar "declarar" y "local" de esta manera actúa como documentación.
EDITAR 1 - (Respuesta al comentario de Karsten a continuación) - No puedo agregar más comentarios a continuación, pero el comentario de Karsten me hizo pensar, así que hice la siguiente prueba que FUNCIONA BIEN, AFACIO - Karsten si lees esto, proporciona un conjunto exacto de pasos de prueba desde la línea de comando, que muestra el problema que usted supone que existe, porque estos pasos siguientes funcionan bien:
$ return_a_string ret; echo $ret
The date is 20170104
(Ejecuté esto justo ahora, después de pegar la función anterior en un término bash, como puede ver, el resultado funciona bien).
function funcName {
es la sintaxis heredada pre-POSIX heredada de ksh temprano (donde tenía diferencias semánticas que bash no respeta).funcName() {
, con nofunction
, debe usarse en su lugar; ver wiki.bash-hackers.org/scripting/obsolete