O Bash permite usar: cat <(echo "$FILECONTENT")
O Bash também permite usar: while read i; do echo $i; done </etc/passwd
para combinar os dois anteriores, pode ser usado: echo $FILECONTENT | while read i; do echo $i; done
O problema com o último é que ele cria um sub-shell e, depois que o loop while termina, a variável i
não pode mais ser acessada.
Minha pergunta é:
Como conseguir algo assim: while read i; do echo $i; done <(echo "$FILECONTENT")
ou em outras palavras: Como posso ter certeza de que i
sobrevive o loop while?
Observe que estou ciente de incluir a instrução while, {}
mas isso não resolve o problema (imagine que você deseja usar o loop while na função e na i
variável de retorno )
bash
while-loop
stdin
pipe
Wakan Tanka
fonte
fonte
lastpipe
e seus prós e contras.Respostas:
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 fica então 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 um subshell. Nesse contexto, eles fazem parte de um pipeline e, portanto, são executados como um subshell, mas é por causa do
|
, não do{ ... }
. Você menciona isso na pergunta. AFAIK, você pode fazer um retorno de dentro deles dentro de uma função.O Bash também fornece o
shopt
integrado e uma de suas muitas opções é:Assim, usar algo assim em um script torna o modificado
sum
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
Fazer isso na linha de comando geralmente resulta na falta de 'controle de trabalho não está ativo' (ou seja, na linha de comando, o controle de trabalho está ativo). O teste sem usar um script falhou.
Além disso, conforme observado por Gareth Rees em sua resposta , às vezes você pode usar uma string here :
while read i; do echo $i; done <<< "$FILECONTENT"
Isso não requer
shopt
; você pode salvar um processo usando-o.fonte
while read i; do echo $i; done < <(cat /etc/passwd); echo $i
ele não retorna a última linha duas vezes. O que estou fazendo errado?i
como vazia, então o eco após o loop ecoa uma linha em branco.while read i; do x=$i; done < <(cat /etc/passwd); echo i=$i; echo x=$x
funcionou, // talvez o comportamento do bash daquela época tenha mudado?Jonathan Leffler explica como fazer o que quiser usando a substituição de processo , mas outra possibilidade é usar uma string here :
while read i; do echo "$i"; done <<<"$FILECONTENT"
Isso salva um processo.
fonte
Esta função duplica $ NUM vezes de arquivos jpg (bash)
function makeDups() { NUM=$1 echo "Making $1 duplicates for $(ls -1 *.jpg|wc -l) files" ls -1 *.jpg|sort|while read f do COUNT=0 while [ "$COUNT" -le "$NUM" ] do cp $f ${f//sm/${COUNT}sm} ((COUNT++)) done done }
fonte