while statement script loop examples while-loop sh

while-loop - statement - while do linux bash



salida de tubería del proceso a sh while loop? (3)

Estoy intentando recorrer la salida de un proceso Perl, línea por línea, dentro de un ciclo while. Sin embargo, estoy teniendo dificultades con la sintaxis.

Intenté esto, pero obtuve un error de "redirección ambigua":

#!/bin/sh while read line; do echo "$line" # do stuff with $line done < $(perl process.pl) ./script.sh : line 6: $(perl process.pl): ambiguous redirect

Por ejemplo, una solución (ineficiente) sería:

#!/bin/sh tmpFile=/tmp/tmpFile.txt perl process.pl > $tmpFile while read line; do echo "$line" # do stuff with $line done < $tmpFile

Sé que puedo canalizar el proceso Perl a un ciclo while como:

perl process.pl | while ...

pero el ciclo while se ejecuta en una subshell, y necesito que algunas variables establecidas en el ciclo while permanezcan después de que termine el ciclo, por lo que esta no es una opción.

¿Que puedo hacer?


Use un documento aquí :

while IFS= read -r line; do echo "$line" # do stuff with $line done <<EOF $(perl process.pl) EOF


Use un tubo con nombre; bash sustitución del proceso de bash es esencialmente azúcar sintáctico alrededor de esto.

mkfifo output perl process.pl > output & while IFS= read -r line; do echo "$line" # do stuff with $line done < output rm output

La tubería con nombre no requiere que process.pl complete antes de que el ciclo while comience a consumir la salida.


Ya casi estás ahí. Prueba esto:

while read -r line; do echo "$line" # do stuff with $line done < <(perl process.pl)

La única diferencia es < lugar de $ .

$(cmd) es una sustitución de comando, que se expande a la salida del comando entre paréntesis. Por otro lado, <(cmd) es una sustitución de proceso . Tenga en cuenta que esta es una extensión de Bash, por lo que también debe cambiar su shebang para que sea #!/bin/bash si desea utilizar este método.

Alternativamente, si no está utilizando Bash, simplemente puede usar una tubería en su lugar:

perl process.pl | while read -r line; do echo "$line" # do stuff with $line done

Como un lado, casi siempre quiere usar el interruptor -r con lectura