Bash permite usar: cat <(echo "$FILECONTENT")
Bash también permite usar: while read i; do echo $i; done </etc/passwd
para combinar los dos anteriores, esto se puede usar: echo $FILECONTENT | while read i; do echo $i; done
El problema con el último es que crea un sub-shell y después de que el ciclo while termina i
ya no se puede acceder a la variable .
Mi pregunta es:
Cómo lograr algo como esto: while read i; do echo $i; done <(echo "$FILECONTENT")
o en otras palabras: ¿Cómo puedo estar seguro de que i
sobrevive while loop?
Tenga en cuenta que soy consciente de incluir la instrucción while en, {}
pero esto no resuelve el problema (imagine que desea usar el bucle while en la función y la i
variable de retorno )
bash
while-loop
stdin
pipe
Wakan Tanka
fuente
fuente
lastpipe
y sus pros y contras.Respuestas:
La notación correcta para la sustitución de procesos es:
while read i; do echo $i; done < <(echo "$FILECONTENT")
El último valor de
i
asignado en el bucle está disponible cuando el bucle termina. Una alternativa es:echo $FILECONTENT | { while read i; do echo $i; done ...do other things using $i here... }
Las llaves son una operación de agrupación de E / S y no crean por sí mismas una subcapa. En este contexto, son parte de una canalización y, por lo tanto, se ejecutan como una subcapa, pero se debe a
|
, no a{ ... }
. Mencionas esto en la pregunta. AFAIK, puede hacer un retorno desde dentro de estos dentro de una función.Bash también proporciona la función
shopt
incorporada y una de sus muchas opciones es:Por lo tanto, usar algo como esto en un script hace que el modificado
sum
esté disponible después del ciclo: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
Hacer esto en la línea de comando generalmente implica una falta de 'control de trabajo no está activo' (es decir, en la línea de comando, el control de trabajo está activo). No se pudo probar esto sin usar un script.
Además, como señaló Gareth Rees en su respuesta , a veces puede usar una cadena aquí :
while read i; do echo $i; done <<< "$FILECONTENT"
Esto no requiere
shopt
; es posible que pueda guardar un proceso usándolo.fuente
while read i; do echo $i; done < <(cat /etc/passwd); echo $i
, no devolvió la última línea dos veces. ¿Que estoy haciendo mal?i
a vacía, por lo que el eco después del ciclo hace eco de una línea en blanco.while read i; do x=$i; done < <(cat /etc/passwd); echo i=$i; echo x=$x
trabajado, // ¿tal vez esos días el comportamiento de bash cambió?Jonathan Leffler explica cómo hacer lo que quiere usando la sustitución de procesos , pero otra posibilidad es usar una cadena aquí :
while read i; do echo "$i"; done <<<"$FILECONTENT"
Esto ahorra un proceso.
fuente
Esta función hace duplicados $ NUM veces de archivos 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 }
fuente