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 $2,$4,$0}' | awk '{print "http://domain.example"$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
째,, 카카를를 늘늘다다다다「」의 변경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++
가독성이 향상된다고 생각하시면요.Python이 "올바른 방법은 하나밖에 없다"고 하는 것이 더 적절할 때 Bash는 Perl 철학에 너무 많은 방법을 너무 많이 제시합니다.그것은 논란의 여지가 있는 진술이다.어쨌든 (이 경우) 단순히 변수를 늘리는 것이 아니라 다른 사람이 이해하고 지원할 수 있는 코드를 작성하는 것이 목적입니다.순응은 그것을 달성하는 데 큰 도움이 된다.
HTH
사용해보십시오.
COUNTER=$((COUNTER+1))
대신
COUNTER=$((COUNTER))
은 당신의 awk 합니다.grep|grep|awk|awk
파이프라인: 테스트해 주세요.마지막 awk 명령어는 전혀 변경되지 않은 것으로 보입니다.
COUNTER의 문제는 while 루프가 서브셸에서 실행 중이기 때문에 서브셸이 종료되면 변수에 대한 모든 변경이 사라집니다.동일한 서브셸에서 COUNTER 값에 액세스해야 합니다.또는 @DennisWilliamson의 조언을 받아들여 프로세스 치환을 사용하고 서브셸을 완전히 회피합니다.
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
}
count=0
base=1
(( count += base ))
파일을 하는 것이 , 파일 됩니다.while
이치노
while ...
do
...
done < <(grep ...)
그 모든 수 예요.grep, grep, awk, awk, awk
가 되어awk
.
4부터는 Bash 4.2가 .lastpipe
option 'so' ()
는 현재 셸 컨텍스트에서 파이프라인의 마지막 명령을 실행합니다.작업 제어를 사용하도록 설정한 경우 lastpipe 옵션은 적용되지 않습니다.
bash -c 'echo foo | while read -r s; do c=3; done; echo "$c"'
bash -c 'shopt -s lastpipe; echo foo | while read -r s; do c=3; done; echo "$c"'
3
미니멀리스트
counter=0
((counter++))
echo $counter
이 표현은 두 가지 조건이 있습니다.((var++))
실패하기 위해:
bash를 strict 모드로 설정했을 경우(
set -euo pipefail
(0부터 증가)를 시작합니다.1부터 시작하는 것은 괜찮지만 0부터 시작하는 것은 "+"를 평가할 때 증가분이 "1"을 반환합니다.이것은 엄밀한 모드에서 0이 아닌 리턴 코드 장애입니다.
사용할 수 있습니다.((var+=1))
또는var=$((var+1))
이 행동에서 벗어나기 위해
이것으로 충분합니다.
$((COUNTER++))
다음은 Learning the bash Shell, 제3판, 147, 148페이지에서 발췌한 것입니다.
bash 산술식은 Java 및 C 언어의 산술식과 동일합니다.[9] 우선순위 및 연관성은 C와 동일합니다.표 6-2는 지원되는 산술 연산자를 보여줍니다.이들 중 일부는 특수문자(또는 포함)이지만 $(...) 구문 내에 있으므로 백슬래시를 이스케이프할 필요가 없습니다.
..........................
++ 및 - 연산자는 값을 1씩 늘리거나 줄이려는 경우에 유용합니다.[11] Java 및 C와 동일하게 동작합니다.예를 들어 value++는 값을 1씩 증가시킵니다.이것을 포스트 인크리먼트라고 부릅니다.전 인크리먼트도 있습니다.++값입니다.그 차이는, 예를 들면 다음과 같습니다.
$ 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=1
for i in {1..5}
do
echo $COUNTER;
//echo "Welcome $i times"
((COUNTER++));
done
소스 스크립트에 하위 셸에 문제가 있습니다.첫 번째 예에서는 서브셸이 필요하지 않을 수 있습니다.근데 'Some more action' 밑에 뭐가 숨겨져 있는지 모르겠어요.가장 일반적인 답변은 I/O를 증가시키는 숨겨진 버그가 있으며, 서브셸에서는 작동하지 않습니다. 왜냐하면 루프 내부에서 쿠터를 복원하기 때문입니다.
'\' 기호를 추가하지 마십시오. bash 인터프리터에 회선 연속에 대해 알려줍니다.당신이나 누구에게도 도움이 되길 바랍니다.단, 이 스크립트는 AWK 스크립트로 완전히 변환하거나 regexp 또는 perl을 사용하여 python으로 다시 작성해야 하지만 perl의 인기는 수년간 저하되고 있습니다.비단뱀으로 하는 게 좋을 거야
수정 버전(서브셸 제외):
#!/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://example.com"$5"&ip="$2"&date="$7"&time="$8"&end=1"}' |\
awk -F '&end=1' '{print $1"&end=1"}' |\
#( #unneeded bracket
while read WFY_URL
do
echo $WFY_URL #Some more action
COUNTER=$((COUNTER+1))
done
# ) unneeded bracket
echo $COUNTER # output = 0
꼭 필요한 경우 하위 셸이 포함된 버전
#!/bin/bash
TEMPFILE=/tmp/$$.tmp #I've got it from the most popular answer
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://example.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 > $TEMPFILE #store counter only once, do it after loop, you will save I/O
)
COUNTER=$(cat $TEMPFILE) #restore counter
unlink $TEMPFILE
echo $COUNTER # output = 0
업데이트하지 않은 것 같습니다.counter
스크립트입니다.사용counter++
언급URL : https://stackoverflow.com/questions/10515964/counter-increment-in-bash-loop-not-working
'programing' 카테고리의 다른 글
Excel의 모든 셀에 공통 접두사 추가 (0) | 2023.04.22 |
---|---|
Xcode 6에서 생성되지 않은 목표 C 헤더로 빠르게 이동 (0) | 2023.04.22 |
vba code Cells에서 Excel 열의 값을 찾는 방법.검색 (0) | 2023.04.22 |
Windows에서 Git Bash를 사용할 때 개인 키를 해독하기 위한 패스워드가 매번 입력되지 않도록 하려면 어떻게 해야 합니까? (0) | 2023.04.22 |
WPF에 Design Mode 속성이 있습니까? (0) | 2023.04.22 |