Приращение счетчика в цикле Bash не работает



у меня есть следующий простой скрипт, где я запускаю цикл и хочу поддерживать COUNTER. Я не могу понять, почему счетчик не обновляется. Это связано в случае, когда это становится создан? Как я могу потенциально исправить это?



#!/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 ,,}' | awk '{print "http://domain.com""&ip=""&date=""&time=""&end=1"}' | awk -F '&end=1' '{print "&end=1"}' |
(
while read WFY_URL
do
echo $WFY_URL #Some more action
COUNTER=$((COUNTER+1))
done
)

echo $COUNTER # output = 0
730   10  

10 ответов:

во-первых, вы не увеличиваем счетчик. Изменение COUNTER=$((COUNTER)) на COUNTER=$((COUNTER + 1)) или COUNTER=$[COUNTER + 1] увеличит его.

во-вторых, это сложнее для обратного распространения переменных подобласти к вызываемому абоненту, как вы предполагаете. Переменные в подобласти недоступны вне этой подобласти. Это переменные, локальные для дочернего процесса.

один из способов решить эту проблему-использовать временный файл для хранения промежуточного значения:

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
COUNTER=1
while [ Your != "done" ]
do
     echo " $COUNTER "
     COUNTER=$[$COUNTER +1]
done

проверено BASH: Centos, SuSE, RH

COUNTER=$((COUNTER+1)) 

- Это довольно неуклюжая конструкция в современном программировании.

(( COUNTER++ ))

выглядит более "современным". Вы также можете использовать

let COUNTER++

Если вы думаете, что это улучшает читаемость. Иногда Bash дает слишком много способов делать вещи-философия Perl, я полагаю, - когда, возможно, Python "есть только один правильный способ сделать это" может быть более подходящим. Это спорное утверждение, если оно вообще было! В любом случае, я бы предложил цель (в данном случае) не просто увеличьте переменную, но (общее правило), чтобы также написать код, который кто-то другой может понять и поддержать. Соответствие проходит долгий путь к достижению этого.

HTH

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

попробуйте использовать

COUNTER=$((COUNTER+1))

вместо

COUNTER=$((COUNTER))

Я думаю, что этот единственный вызов awk эквивалентен вашему : пожалуйста, проверьте его. Ваша последняя команда awk, похоже, ничего не меняет.

проблема со счетчиком заключается в том, что цикл while выполняется в подрешетке, поэтому любые изменения переменной исчезают при выходе из подрешетки. Вам нужно получить доступ к значению счетчика в той же подрешетке. Или возьмите совет @DennisWilliamson, используйте подстановку процесса и вообще избегайте подрешетки.

awk '
  /GET \/log_/ && /upstream timed out/ {
    split(, a, ", ")
    split(a[2] FS a[4] FS , 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
}

вместо использования временного файла, вы можете избежать создания подобласти вокруг while цикл с помощью подстановки процесса.

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

кстати, вы должны быть в состоянии преобразовать все, что grep, grep, awk, awk, awk в одном awk.

минимализм

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

Это все, что вам нужно сделать:

$((COUNTER++))

вот отрывок из изучение оболочки bash, 3-е издание, стр. 147, 148:

Баш арифметические выражения эквивалентны своим аналогам в Java и C языки.[9] приоритет и ассоциативность одинаковы как и в C. таблица 6-2 показывает арифметические операторы, которые поддерживаются. Хотя некоторые из них являются (или содержат) специальные символы, есть нет необходимости обратная косая черта-избежать их, потому что они находятся в пределах $((...)) синтаксис.

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

операторы ++ и - полезны, когда вы хотите увеличить или уменьшить значение на единицу.[11] они работают так же, как в Java и C, например, стоимостью++ увеличивает значение на 1. Это называется пост-инкремент; существует также pre-increment:++стоимостью. Разница становится очевидной с пример:

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

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

похоже, что вы не обновили counter сценарий, используйте counter++

Comments

    Ничего не найдено.