나는 다음의 솔루션을 사용했습니다.이 답변내가 작성하고 있는 스크립트에서는 작동하지 않는 것 같습니다. 배쉬 5를 사용하고 있습니다. 이것은 단순화된 테스트 케이스입니다. do_thing
함수가 5분의 배수로 호출되기를 원하지만( 실제 스크립트에서는 메인 프로그램 시작 부분에서 루프를 트리거하기 때문에 $min
및 동일하지 않은 경우) 실행하면 또한 트리거됩니다. 이 Multiple + 1이므로 분명히 어딘가에 하나씩 또는 수학 오류가 약간 있지만 표시되지 않습니다. 어떤 아이디어가 있나요?$minutes
do_thing
#!/usr/bin/env bash
minutes=6
sec=00
min="$minutes"
do_thing() {
echo 'done thing'
}
while [ "$min" -ge 0 ]; do
remainder=$(( min % 5 ))
# TODO: this is broken
[ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ] && do_thing
while [ $sec -ge 0 ]; do
echo "$min $sec"
((sec=sec-1))
sleep 1
done
sec=59
((min=min-1))
done
답변1
set -x
Bash 스크립트를 디버깅할 때 가장 먼저 해야 할 일은 맨 위에 추가하는 것입니다. 이를 통해 스크립트가 수행하는 작업, 루프의 각 반복에서 각 테스트의 모양 등을 확인할 수 있습니다.
내가 넣을 곳은 다음과 같습니다.
#!/usr/bin/env bash
# NOTE: Remove or comment the below line when you're done debugging!
set -x
minutes=6
sec=00
...
디버깅하는 동안 코드 전체에 분산시키면 echo "myvar = $myvar"
스크립트의 주요 지점에서 변수 값을 추적하여 예상되는 값과 비교할 수 있습니다.
논리의 결함은 일단 "분 카운터" 루프를 종료할 수 있는 조건을 얻으면,즉시 최소값을 1로 줄입니다.따라서 나머지를 다시 계산하면 항상 하나가 줄어듭니다. 당신은 "카운터"를 줄이고 있습니다앞으로원하는 계산을 수행하는 데 사용됩니다!
논리적으로 초 = 0을 테스트하고 싶습니다.그 다음에나머지를 계산하고,그 다음에다음 루프를 설정합니다.
#!/usr/bin/env bash
#set -x
minutes=6
sec=00
min="$minutes"
do_thing() {
echo 'done thing'
}
while [ "$min" -ge 0 ]; do
while [ $sec -ge 0 ]; do
echo "$min $sec"
((sec=sec-1))
sleep 1
done
remainder=$(( min % 5 ))
# Added echo for debugging
echo "remainder = $remainder"
[ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ] && do_thing
sec=59
((min=min-1))
done
여기서 또 눈에 띄는 점은 -매우&&
and 에 주의하세요 ||
. 빠르고 지저분한 경우에는 괜찮지만, 복잡한 논리의 경우에는 속일 수 있습니다!
이러한 논리 연산자는아니요대안이 있다고 하더라도 적절하게 테스트하십시오.때때로- 테스트 사용과의 한 가지 차이점은 if []; then...
종료 코드를 자동으로 사용한다는 것입니다. 주의 깊게 읽고 ()
원하는 작업 순서를 적용하기 위해 사용하지 않고는 둘 이상을 연속해서 사용하지 마십시오 .
내 조언을 받아들이고 여기를 피하고 싶다면 &&
다음 방법이 있습니다(중첩된 `if는 다른 방법이지만 필요하지 않으면 사용하지 않는 것이 좋습니다).
...
remainder=$(( min % 5 ))
# Added echo for debugging
echo "remainder = $remainder"
if ([ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ]); then
do_thing
fi
sec=59
((min=min-1))
...