Problema con variables en un bucle que está en una tubería

Se tarda en leer ~1 minuto

TL; DR

Cada comando de una tubería se ejecuta dentro de una subshell, con su propio contexto y entorno de variables. Incluyendo los bucles si estos forman parte de la tubería.

La variable que desaparecía

El otro día trabajando con un script en bash me volví un poco loco con una variable que modificaba dentro de un bucle while y que luego parecía no guardar su valor una vez terminado el bucle. Como era un comportamiento que para nada esperaba me costó lo mio dar con el problema. No era un problema del bucle, si no de que éste formaba parte de una tubería (pipe):

var1=0
echo $VARIABLE1 | 
while read task; do
  # cuerpo del bucle
  var1=2
  # ...
done
echo "$var1"


> 0

Efectivamente, cada comando de una tubería se ejecuta dentro de una subshell, con su propio contexto y entorno de variables. Incluyendo los bucles si estos forman parte de la tubería.

En esta web se puede leer una descripción detallada de este comportamiento, qué sucede en las diferentes versiones de shell, así como diferentes maneras de sortearlo.

De las propuestas, la solución que decidí adoptar en mi caso fue el agrupamiento de comandos (Command grouping) así:

var1=0
 
echo $VARIABLE1 |
{ 
  while read task; do
    # cuerpo del bucle
    var1=2
    # ...
  done
  echo "$var1"
}

> 2

Que, como explican en la página, no altera para nada el tema de la subshell, pero como en este caso no necesitaba reutilizar nada de lo que allí había en el resto del código, resulta una solución suficiente y rápida de aplicar.

De paso, he descubierto esta página que parece que va a ser una referencia útil a la que volver de vez en cuando.

Fuente:

BashFAQ

Comentarios


Programación funcional

> Los tres principales criterios de la programción funcional como paradigma de computación se pueden resumir:1. Cualquier operación se pu...… Seguir leyendo

Renombrar ficheros con git

Publicado el 17 de octubre de 2019

Inicio de arrays

Publicado el 14 de septiembre de 2019