Bash - 如果某些内容为真,则在while循环中递增计数器

时间:2014-07-24 08:07:06

标签: bash loops

我想在while循环中递增一个计数器,一旦该循环完成,就会回显计数器。 $ COUNTER只应在$DATE >= $SINCE

时递增
   last -f /var/log/btmp |
while read line; do
    set -- $line
    [[ $1 == "$CURRENTUSER" ]] || continue
    [[ $(date -d "$4 $5 $6 $7" +%Y%m%d%H%M%S) -ge $SINCE ]] && echo "FAILED LOGIN $line" && ((COUNTER+=1))
    echo $COUNTER //echos 1, 2 etc
done

echo "Top counter:"$COUNTER //echos 0 

3 个答案:

答案 0 :(得分:1)

你的问题在于这一行:

[[ $(date -d "$4 $5 $6 $7" +%Y%m%d%H%M%S) -ge $since ]] && echo "$line && COUNTER=$[$COUNTER +1]"

您需要以下内容:

[[ $(date -d "$4 $5 $6 $7" +%Y%m%d%H%M%S) -ge $since ]] && echo "$line" && ((COUNTER+=1))

如果要显示和增加,则:

[[ $(date -d "$4 $5 $6 $7" +%Y%m%d%H%M%S) -ge $since ]] && echo "$line $((COUNTER+=1))"

答案 1 :(得分:0)

问题是范围之一。管道进入while表示$ COUNTER超出范围。一个很好的解释是http://mywiki.wooledge.org/BashFAQ/024

解决方案来自Chris对此帖的评论:

http://www.edwardawebb.com/linux/scope-issue-bash-loops enter link description here

COUNTER=0

STDOUT=$(last -f /var/log/btmp)

        while read line; do
            set -- $line
            [[ $1 == "$CURRENTUSER" ]] || continue
            [[ $(date -d "$4 $5 $6 $7" +%Y%m%d%H%M%S) -ge $SINCE ]] && echo "FAILED LOGIN $line" && ((COUNTER+=1))
        done <<EOF

        $STDOUT
        EOF

        echo "counter:$COUNTER"

答案 2 :(得分:0)

管道命令在每个子shell中执行。变量修改仅限于该子shell,并且不会传播回父shell。

使用bash,避免陷阱的常见解决方法是使用进程替换

while read line; do
    set -- $line
    [[ $1 == "$CURRENTUSER" ]] || continue
    [[ $(date -d "$4 $5 $6 $7" +%Y%m%d%H%M%S) -ge $SINCE ]] && echo "FAILED LOGIN $line" && ((COUNTER+=1))
    echo $COUNTER //echos 1, 2 etc
done < <(last -f /var/log/btmp)
#    ^^^^^^^^^^^^^^^^^^^^^^^^^^