Tengo un problema en uno de mis scripts de shell. Pregunté a algunos colegas, pero todos menearon la cabeza (después de rascarse), así que he venido aquí por una respuesta.
Según tengo entendido, el siguiente script de shell debería imprimir "Count is 5" como la última línea. Excepto que no. Imprime "El recuento es 0". Si el "while read" se reemplaza con cualquier otro tipo de bucle, funciona bien. Aquí está el guión:
echo "1"> input.data echo "2" >> input.data echo "3" >> input.data echo "4" >> input.data echo "5" >> input.data CNT = 0 cat input.data | mientras lee; hacer dejar CNT ++; echo "Contando a $ CNT" hecho echo "El recuento es $ CNT"
¿Por qué sucede esto y cómo puedo evitarlo? He intentado esto en Debian Lenny y Squeeze, el mismo resultado (es decir, bash 3.2.39 y bash 4.1.5. Admito plenamente que no soy un asistente de script de shell, por lo que cualquier puntero sería apreciado.
Esto es una especie de error 'común'. Las tuberías crean SubShells, por lo que
while read
se ejecuta en un shell diferente al de su script, lo que hace que suCNT
variable nunca cambie (solo la que está dentro del subshell de la tubería).Agrupe el último
echo
con el subshellwhile
para arreglarlo (hay muchas otras formas de arreglarlo, esta es una. Las respuestas de Iain e Ignacio tienen otras).Larga explicación:
CNT
en su script como valor 0;|
awhile read
;$CNT
variable se exporta a SubShell con el valor 0;CNT
valor a 5;echo
suCNT
valor original de 0.fuente
Esto funciona
fuente
let CNT++
que debería serCNT="$((CNT+1))"
para usar la expansión aritmética compatible con POSIX . El resto ya es portátil.Intente pasar los datos en un subconjunto, como si fuera un archivo antes del ciclo while. Esto es similar a la solución de lain, pero supone que no desea algún archivo intermitente:
fuente