Como canalizar a input para um Bash while loop e preservar as variables ​​após o final do loop

Bash permite usar: cat <(echo "$FILECONTENT")

Bash também permite usar: while read i; do echo $i; done </etc/passwd while read i; do echo $i; done </etc/passwd

para combinar os dois anteriores isso pode ser usado: echo $FILECONTENT | while read i; do echo $i; done echo $FILECONTENT | while read i; do echo $i; done

O problema com o último é que ele cria sub-shell e depois que o loop while termina a variável i não posso mais ser acessado.

Minha pergunta é:

Como conseguir algo assim: while read i; do echo $i; done <(echo "$FILECONTENT") while read i; do echo $i; done <(echo "$FILECONTENT") while read i; do echo $i; done <(echo "$FILECONTENT") ou em outras palavras: Como posso ter certeza de que i sobrevive enquanto loop?

Por favor, note que estou ciente de include a declaração em {} mas isso não resolve o problema (imagine que você quer usar o laço while na function e retornar a variável i )

A notação correta para Substituição de Processo é:

 while read i; do echo $i; done < <(echo "$FILECONTENT") 

O último valor de i atribuído no loop está disponível quando o loop termina. Uma alternativa é:

 echo $FILECONTENT | { while read i; do echo $i; done ...do other things using $i here... } 

As chaves são uma operação de agrupamento de E / S e não criam uma subcamada. Neste contexto, eles são parte de um pipeline e, portanto, são executados como um subshell, mas é por causa do | não o { ... } . Você mencionou isso na pergunta. AFAIK, você pode fazer um retorno dentro de uma function.


O Bash também fornece o shopt e uma de suas muitas opções é:

lastpipe

Se definido e o controle de tarefa não estiver ativo, o shell executará o último comando de um pipeline não executado em segundo plano no ambiente atual do shell.

Assim, usar algo assim em um script torna a sum modificada disponível após o loop:

 FILECONTENT="12 Name 13 Number 14 Information" shopt -s lastpipe # Comment this out to see the alternative behaviour sum=0 echo "$FILECONTENT" | while read number name; do ((sum+=$number)); done echo $sum 

Fazendo isso na linha de comando, geralmente ocorre falta de controle de trabalho não está ativo (isto é, na linha de comando, o controle de trabalho está ativo). Testar isso sem usar um script falhou.

Além disso, como observado por Gareth Rees em sua resposta , às vezes você pode usar uma string aqui :

 while read i; do echo $i; done <<< "$FILECONTENT" 

Isso não requer shopt ; você pode salvar um processo usando-o.

Jonathan Leffler explica como fazer o que você quer usando a substituição de processos , mas outra possibilidade é usar uma string aqui :

 while read i; do echo "$i"; done <<<"$FILECONTENT" 

Isso salva um processo.

Intereting Posts