Establecer una variable de shell principal a partir de una subshell

¿Cómo configuro una variable en el shell principal desde una subshell?

a=3 (a=4) echo $a 

El objective de una subshell es que no afecta la sesión de llamada. En bash, una subshell es un proceso hijo, otras shells difieren, pero aun así una configuración de variable en una subshell no afecta a la persona que llama. Por definición.

¿Necesitas una subshell? Si solo necesitas un grupo, utiliza llaves:

 a=3 { a=4;} echo $a 

da 4 (tenga cuidado de los espacios en ese). Alternativamente, escriba el valor de la variable en stdout y capturelo en la persona que llama:

 a=3 a=$(a=4;echo $a) echo $a 

evite usar back-ticks “, están en desuso y pueden ser difíciles de leer.

Está el truco de la variable gdb-bash:

 gdb --batch-silent -ex "attach $$" -ex 'set bind_variable("a", "4", 0)'; 

aunque eso siempre establece una variable en el ámbito global, no solo el scope principal

Tu no La subshell no tiene acceso al entorno de sus padres. (Al menos dentro de la abstracción que proporciona Bash. Podría potencialmente intentar usar gdb , o romper la stack, o lo que sea, para obtener ese acceso de forma clandestina. Sin embargo, no lo recomendaría).

Una alternativa es que la subshell escriba las sentencias de asignación en un archivo temporal para que lea su padre:

 a=3 (echo 'a=4' > tmp) . tmp rm tmp echo "$a" 

Si el problema está relacionado con un ciclo while, una forma de solucionarlo es mediante la sustitución de procesos:

  var=0 while read i; do # perform computations on $i ((var++)) done < <(find . -type f -name "*.bin" -maxdepth 1) 

como se muestra aquí: https://stackoverflow.com/a/13727116/2547445

Puede generar el valor en la subshell y asignar la salida de la subshell a una variable en el script de la persona que llama:

 # subshell.sh echo Value # caller myvar=$(subshell.sh) 

Si la subshell tiene más resultados, puede separar el valor de la variable y otros mensajes redirigiéndolos a diferentes flujos de salida:

 # subshell.sh echo "Writing value" 1>&2 echo Value # caller myvar=$(subshell.sh 2>/dev/null) # or to somewhere else echo $myvar 

Alternativamente, puede generar asignaciones de variables en la subcadena, evaluarlas en el script de llamante y evitar el uso de archivos para intercambiar información:

 # subshell.sh echo "a=4" # caller # export $(subshell.sh) would be more secure, since export accepts name=value only. eval $(subshell.sh) echo $a 

La última forma en que puedo pensar es usar códigos de salida, pero esto cubre el intercambio de valores enteros solamente (y en un rango limitado) y rompe la convención para interpretar códigos de salida (0 para el éxito no 0 para todo lo demás).

Para cambiar las variables en una secuencia de comandos llamada desde una secuencia de comandos primaria, puede llamar al script precedido por un “.”

 a=3 echo $a . ./calledScript.sh echo $a 

en calledScript.sh

 a=4 

Rendimiento esperado

 3 4