간단한 스크립트를 사용해 보고 싶습니다.
flag=false
while !$flag
do
read x
if [ "$x" -eq "true" ]
then
flag=true
fi
echo "${x} : ${flag}"
done
그런데 실행할 때 를 입력하면 and가 true
표시되지만 루프가 끝나지 않습니다. 스크립트에 어떤 문제가 있나요? 부울 변수를 올바르게 반전시키는 방법은 무엇입니까?x="true"
flag="true"
답변1
스크립트에 두 가지 오류가 있습니다. 첫 번째는 !
과 사이에 공백이 있어야 한다는 것입니다 $flag
. 그렇지 않으면 쉘은 이라는 명령을 찾습니다 !$flag
. 두 번째 오류는 -eq
정수 비교를 위한 것이지만 문자열에 사용하고 있습니다. 쉘에 따라 오류 메시지가 표시될 수 있으며 조건이 true가 될 수 없거나 정수가 아닌 모든 값이 0으로 처리되기 때문에 루프가 영원히 계속됩니다. 를 포함한 문자열을 입력하면 [ "$x" -eq "true" ]
루프가 false
다음이 아닌 숫자로 종료됩니다. 0.
이것이 맞기 는 하지만 ! $flag
문자열을 명령으로 취급하는 것은 좋지 않습니다. 작동하지만 스크립트의 변경 사항에 매우 민감합니다. 또는 이외의 것이 $flag
아닌지 확인해야 하기 때문입니다 . 여기서는 아래 테스트처럼 문자열 비교를 사용하는 것이 더 좋습니다.true
false
flag=false
while [ "$flag" != "true" ]
do
read x
if [ "$x" = "true" ]
then
flag=true
fi
echo "${x} : ${flag}"
done
당신이 추구하는 논리를 표현하는 더 좋은 방법이 있을 것입니다. 예를 들어 무한 루프를 생성하고 종료 조건이 감지되면 이를 중단할 수 있습니다.
while true; do
read -r x
if [ "$x" = "true" ]; then break; fi
echo "$x: false"
done
답변2
Bash에는 부울 변수가 없지만 산술 평가를 사용하여 이를 에뮬레이트하는 것은 매우 쉽습니다.
flag= # False
flag=0 # False
flag=1 # True (actually any integer number != 0 will do, but see remark below about toggling)
flag="some string" # Maybe False (make sure that the string isn't interpreted as a number)
if ((flag)) # Test for True
then
: # do something
fi
if ! ((flag)) # Test for False
then
: # do something
fi
flag=$((1-flag)) # Toggle flag (only works when flag is either empty or unset, 0, 1, or a string which doesn't represent a number)
이것은 ksh에서도 작동합니다. 모든 POSIX 호환 쉘에서 작동하더라도 놀라지 않을 것입니다. 그러나 아직 표준을 확인하지 않았습니다.
답변3
변수에 0이나 1이 포함될 것이라고 확신하는 경우 비트 XOR 등호 연산자를 사용하여 두 값 사이를 전환할 수 있습니다.
$ foo=0
$ echo $foo
0
$ ((foo ^= 1))
$ echo $foo
1
$ ((foo ^= 1))
$echo $foo
0
답변4
쉘에는 부울 변수 개념이 없습니다.
쉘 변수는 (문자열)만 가능하며 text
어떤 경우에는 텍스트가 정수( 1
, 0xa
등 010
)로 해석될 수 있습니다.
따라서 a는 flag=true
쉘에 대해 참 또는 거짓을 전혀 의미하지 않습니다.
끈
수행할 수 있는 작업은 문자열 비교 [ "$flag" == "true" ]
또는 일부 명령에서 변수 내용을 사용하여 확인하는 것입니다.그 결과, 명령으로 실행 (이름이 지정된 실행 파일 과 이름이 지정된 실행 파일이 true
모두 있으므로 )하고 해당 명령의 종료 코드가 0(성공)인지 확인하는 것과 같습니다.true
false
$flag; if [ "$?" -eq 0 ]; then ... fi
또는 더 짧게:
if "$flag"; then ... fi
변수의 내용이 명령으로 사용되는 경우 다음과 같이 둘 사이에 공백( )이 있으면 a를 !
사용하여 명령의 종료 상태를 무효화할 수 있습니다.! cmd
if ! "$flag"; then ... fi
스크립트는 다음과 같이 변경되어야 합니다.
flag=false
while ! "$flag"
do
read x
if [ "$x" == "true" ]
then
flag=true
fi
echo "${x} : ${flag}"
done
정수
숫자와산술 확장.
이 경우의 종료 코드 $((0))
는 이고 1
, 종료 코드는 $((1))
입니다 0
.
bash, ksh 및 zsh에서는 a 내에서 산술을 수행할 수 있습니다( ((..))
시작 부분이 없음에 주의).$
flag=0; if ((flag)); then ... fi
이 코드의 이식 가능한 버전은 더 복잡합니다.
flag=0; if [ "$((flag))" -eq 0 ]; then ... fi # test for a number
flag=0; if [ "$((flag))" == 0 ]; then ... fi # test for the string "0"
bash/ksh/zsh에서는 다음을 수행할 수 있습니다.
flag=0
while ((!flag))
do
read x
[ "$x" == "true" ] && flag=1
echo "${x} : ${flag}"
done
또는
"부울 변수를 반전"할 수 있습니다(숫자 값이 포함된 경우).
((flag=!flag))
그럴 것이다변화flag
또는 0
가치 1
.
노트: 오류가 있는지 확인해주세요.https://www.shellcheck.net/많은 경우 이는 코드를 이슈로 게시하기 전에 문제를 찾는 데 충분합니다.