Imprima variables desde el subshell al shell principal

Imprima variables desde el subshell al shell principal

Muy nuevo en Bash y bastante confundido acerca de las variables/subcapas locales/globales. No estoy seguro de por qué las variables modificadas no se imprimen al final de la función. Estoy intentando imprimir un recuento final de líneas y un recuento de archivos al final del archivo, pero si lo hago, solo se imprime. out 0 porque son variables locales. ¿Hay alguna forma de imprimir los valores modificados?

count=0
files=0
find . -type f | while IFC= read -r file;
do
   let files=files+1
   wc -l $file
   count=$(($count+$(wc -l < $file)))
   echo "total lines $count ; total files $files"
done
echo $files $count
exit 0

Respuesta1

Sí. Pero es absolutamente no intuitivo. Esto funcionará, por ejemplo:

#!/bin/bash
count=0
files=0
while IFS= read -r file;
do
   let files=files+1
   wc -l $file
   count=$(($count+$(wc -l < $file)))
   echo "total lines $count ; total files $files"
done < <(find . -type f )
echo "$files $count"
exit 0

La <(command)construcción se llama"proceso de sustitución"y le permite tratar la salida de un comando como un "archivo". Introducirlo en el bucle de esta manera hace que su script funcione como espera.

El problema es el uso de la tubería ( |), lo que hace que el bucle while se ejecute en un subshell separado que no puede modificar variables fuera de él.

En shells que no admiten la <()función, puede ejecutar los comandos a la derecha de la tubería en una subventa e incluir el eco final en esa subcapa:

#!/bin/bash
files=0
find . -type f | {
    while IFC= read -r file;
    do
        let files=files+1
        wc -l $file
        count=$(($count+$(wc -l < $file)))
        echo "total lines $count ; total files $files"
    done
    echo "$files $count"
}

exit 0

información relacionada