scripts script programas ejemplos contador comando linux bash shell scripting counter

linux - programas - scripts bash ejemplos



El incremento del contador en el bucle Bash no funciona (10)

Tengo el siguiente script simple en el que estoy ejecutando un ciclo y quiero mantener un COUNTER . No puedo entender por qué el contador no se está actualizando. ¿Es debido a la subshell que se está creando? ¿Cómo puedo solucionar esto?

#!/bin/bash WFY_PATH=/var/log/nginx WFY_FILE=error.log COUNTER=0 grep ''GET /log_'' $WFY_PATH/$WFY_FILE | grep ''upstream timed out'' | awk -F '', '' ''{print $2,$4,$0}'' | awk ''{print "http://domain.com"$5"&ip="$2"&date="$7"&time="$8"&end=1"}'' | awk -F ''&end=1'' ''{print $1"&end=1"}'' | ( while read WFY_URL do echo $WFY_URL #Some more action COUNTER=$((COUNTER+1)) done ) echo $COUNTER # output = 0


Creo que este single awk call es equivalente a grep|grep|awk|awk pipeline: por favor, pruébelo. Su último comando awk parece no cambiar nada en absoluto.

El problema con COUNTER es que el ciclo while se está ejecutando en una subcadena, por lo que cualquier cambio en la variable desaparecerá cuando la subshell se cierre. Necesita acceder al valor de COUNTER en esa misma subcadena. O tome el consejo de @DennisWilliamson, utilice una sustitución de proceso y evite por completo la subshell.

awk '' /GET //log_/ && /upstream timed out/ { split($0, a, ", ") split(a[2] FS a[4] FS $0, b) print "http://example.com" b[5] "&ip=" b[2] "&date=" b[7] "&time=" b[8] "&end=1" } '' | { while read WFY_URL do echo $WFY_URL #Some more action (( COUNTER++ )) done echo $COUNTER }


En lugar de utilizar un archivo temporal, puede evitar la creación de una subcadena en el ciclo while utilizando la sustitución de proceso.

while ... do ... done < <(grep ...)

Por cierto, deberías poder transformar todo ese grep, grep, awk, awk, awk en un solo awk .


Esto es todo lo que necesitas hacer:

$((COUNTER++))

Aquí hay un extracto de Learning the bash Shell , 3rd Edition, pp. 147, 148:

Las expresiones aritméticas bash son equivalentes a sus contrapartidas en los lenguajes Java y C. [9] La precedencia y la asociatividad son las mismas que en C. La tabla 6-2 muestra los operadores aritméticos que son compatibles. Aunque algunos de estos son (o contienen) caracteres especiales, no hay necesidad de barras diagonales-escapar de ellos, porque están dentro de la sintaxis $ ((...)).

..........................

Los operadores ++ y - son útiles cuando desea incrementar o disminuir un valor por uno. [11] Funcionan igual que en Java y C, por ejemplo, value ++ incrementa el valor en 1. Esto se denomina incremento posterior ; también hay un incremento previo : valor ++. La diferencia se vuelve evidente con un ejemplo:

$ i=0 $ echo $i 0 $ echo $((i++)) 0 $ echo $i 1 $ echo $((++i)) 2 $ echo $i 2

Ver http://www.safaribooksonline.com/a/learning-the-bash/7572399/


Parece que no actualizaste el counter es el script, usa counter++


Primero, no estás aumentando el contador. Cambiar COUNTER=$((COUNTER)) en COUNTER=$((COUNTER + 1)) o COUNTER=$[COUNTER + 1] lo aumentará.

En segundo lugar, es más complicado propagar hacia atrás las variables de subcadena al destinatario de la llamada como supones. Las variables en una subcadena no están disponibles fuera de la subcadena. Estas son variables locales al proceso hijo.

Una forma de resolverlo es usar un archivo temporal para almacenar el valor intermedio:

TEMPFILE=/tmp/$$.tmp echo 0 > $TEMPFILE # Loop goes here # Fetch the value and increase it COUNTER=$[$(cat $TEMPFILE) + 1] # Store the new value echo $COUNTER > $TEMPFILE # Loop done, script done, delete the file unlink $TEMPFILE


Tratar de usar

COUNTER=$((COUNTER+1))

en lugar de

COUNTER=$((COUNTER))


minimalista

counter=0 ((counter++)) echo $counter


COUNTER=$((COUNTER+1))

es una construcción bastante torpe en la programación moderna.

(( COUNTER++ ))

se ve más "moderno". También puedes usar

let COUNTER++

si crees que mejora la legibilidad A veces, Bash da demasiadas formas de hacer las cosas, supongo que la filosofía Perl, cuando quizás Python "solo hay una forma correcta de hacerlo" podría ser más apropiado. ¡Esa es una declaración discutible si alguna vez hubo una! De todos modos, sugeriría que el objetivo (en este caso) no es simplemente incrementar una variable, sino (regla general) también escribir código que otra persona pueda entender y apoyar. La conformidad hace un largo camino para lograr eso.

HTH


COUNTER=1 while [ Your != "done" ] do echo " $COUNTER " COUNTER=$[$COUNTER +1] done

BASH PROBADO: Centos, SuSE, RH


count=0 base=1 (( count += base ))