Imprime variáveis de subshell para shell pai [duplicado]

1

Muito novo no Bash e bastante confuso sobre variáveis / sub-listas locais / globais. Não sei por que as variáveis modificadas não serão impressas no final da função - estou tentando imprimir uma contagem final de linhas e arquivos no final do arquivo, mas, se o fizer, só imprime. out 0 porque são variáveis locais. Existe alguma maneira de imprimir os 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
    
por novel 29.11.2017 / 19:22

1 resposta

1

Sim. Mas é absolutamente não intuitivo. Isso funcionará, por exemplo:

#!/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

A construção <(command) é chamada "substituição de processo" e permite tratar a saída de um comando como um "arquivo". Alimentá-lo no loop dessa maneira faz seu script funcionar conforme o esperado.

O problema é o uso do pipe ( | ), que faz com que o loop while seja executado em um subshell separado, que não pode modificar variáveis fora dele.

Em shells que não suportam o recurso <() , você pode executar o (s) comando (s) à direita do pipe em um subsell e incluir o eco final nesse subshell:

#!/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
    
por 29.11.2017 / 19:32

Tags