programing

셸 스크립트에서 부울 변수를 선언하고 사용하려면 어떻게 해야 합니까?

lastmemo 2023. 5. 11. 23:53
반응형

셸 스크립트에서 부울 변수를 선언하고 사용하려면 어떻게 해야 합니까?

다음 구문을 사용하여 셸 스크립트에서 부울 변수를 선언하려고 했습니다.

variable=$false

variable=$true

이거 맞는건가요?또한 해당 변수를 업데이트하려면 동일한 구문을 사용해야 합니까?마지막으로, 부울 변수를 표현식으로 사용하기 위한 다음 구문이 맞습니까?

if [ $variable ]

if [ !$variable ]

수정된 답변(2014년 2월 12일)

the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
    echo 'Be careful not to fall off!'
fi

원답

주의사항: https://stackoverflow.com/a/21210966/89391

the_world_is_flat=true
# ...do something interesting...
if $the_world_is_flat ; then
    echo 'Be careful not to fall off!'
fi

시작: Bash에서 부울 변수 사용

여기에 원답이 포함된 이유는 2014년 2월 12일 개정 전 댓글은 원답과 관련된 것일 뿐, 수정된 답변과 연관되었을 때 틀린 댓글이 많기 때문입니다.예를 들어, Dennis Williamson의 bash에 대한 코멘트는 내장되어 있습니다.true2010년 6월 2일에 수정된 것이 아니라 원래 답변에만 적용됩니다.

TL;DR

my_bool=true

if [ "$my_bool" = true ]

Miku의 (원본) 답변에 문제가 있습니다.

저는 수락된1 답변을 추천하지 않습니다.구문은 예쁘지만 몇 가지 결점이 있습니다.

다음과 같은 조건이 있다고 가정합니다.

if $var; then
  echo 'Muahahaha!'
fi

다음과2 같은 경우 이 조건은 중첩된 명령을 true로 평가하고 실행합니다.

# Variable var not defined beforehand. Case 1
var=''  # Equivalent to var="".      # Case 2
var=                                 # Case 3
unset var                            # Case 4
var='<some valid command>'           # Case 5

변수인 "Boolean" 변수가 "Boolean" .var이 예에서 은 true로 명시적으로 설정됩니다.다른 모든 사례들은 위험할 정도로 오해를 불러일으킵니다!

마지막 경우(#5)는 변수에 포함된 명령을 실행하기 때문에 특히 부적절합니다(이것이 유효한3, 4 명령에 대해 조건이 true로 평가되는 이유입니다).

다음은 무해한 예입니다.

var='echo this text will be displayed when the condition is evaluated'
if $var; then
  echo 'Muahahaha!'
fi

# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!

를 따옴표로 묶는 안전합니다( 변수를인용더안다니합전이것는하다니▁quoting▁is).if "$var"; then위의 경우 명령을 찾을 수 없다는 경고가 표시됩니다.하지만 우리는 여전히 더 잘 할 수 있습니다(아래에 있는 제 권장 사항 참조).

Mike Holt의 원래 답변에 대한 Mike Holt의 설명도 참조하십시오.

Hbar의 답변과 관련된 문제

이 접근 방식에는 예상치 못한 동작도 있습니다.

var=false
if [ $var ]; then
  echo "This won't print, var is false!"
fi

# Outputs:
# This won't print, var is false!

위의 조건이 거짓으로 평가되어 중첩된 문을 실행하지 않을 것으로 예상됩니다.놀랐지!

따옴표로 ."false"()를 인용합니다."$var" , 사용합니다.test또는[[[차이를 만들지 않습니다.

가 추천하는 것:

다음은 "Booleans"를 확인하는 것을 추천하는 방법입니다.그들은 예상대로 일합니다.

my_bool=true

if [ "$my_bool" = true ]; then
if [ "$my_bool" = "true" ]; then

if [[ "$my_bool" = true ]]; then
if [[ "$my_bool" = "true" ]]; then
if [[ "$my_bool" == true ]]; then
if [[ "$my_bool" == "true" ]]; then

if test "$my_bool" = true; then
if test "$my_bool" = "true"; then

그들은 모두 거의 동등합니다.다른5 답변보다 키 입력을 몇 개 더 입력해야 하지만 코드가 더 방어적입니다.


각주

  1. Miku의 답변은 그 이후로 편집되었고 더 이상 (알려진) 결함을 포함하지 않습니다.
  2. 전체 목록이 아닙니다.
  3. 이 컨텍스트에서 유효한 명령은 존재하는 명령을 의미합니다.명령어가 올바르게 사용되는지 또는 잘못 사용되는지는 중요하지 않습니다.예.man woman이러한 관리 페이지가 없더라도 유효한 명령으로 간주됩니다.
  4. 잘못된(존재하지 않는) 명령의 경우 Bash는 명령을 찾을 수 없다고 불평합니다.
  5. 길이에 신경을 쓴다면 첫 번째 추천이 가장 짧습니다.

바시가 내장된 것에 대해 여기서 오해가 있는 것 같습니다.true구체적으로는 Bash가 괄호 안의 식을 확장하고 해석하는 방법에 대해 설명합니다.

miku의 답변에 있는 코드는 내장된 Bash와 전혀 관련이 없습니다.true,도 아니다/bin/true 맛의 른어떤맛의것도다▁any▁of도▁nor▁flavor▁other것▁the의른다.true지휘권이 경우에는,true문자열에 단한 문불며과하없에, ▁to▁▁call에 대한 호출은 없습니다.true명령/기본 제공은 변수 할당이나 조건식의 평가를 통해 수행되지 않습니다.

다음 코드는 miku의 답변에 있는 코드와 기능적으로 동일합니다.

the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
    echo 'Be careful not to fall off!'
fi

여기서 유일한 차이점은 비교되는 네 개의 문자가 't', 'r', 'u', 'e'가 아닌 'y', 'e', 'a', 'h'라는 것입니다.바로 그겁니다.이름이 지정된 명령이나 내장된 명령을 호출하려는 시도가 없습니다.yeah (미쿠의에서) Bash가 Bash를 구문 할 때 true그것은 단지 끈일 뿐이고, 그것은 완전히 임의적인 것입니다.

업데이트(2014-02-19): miku의 답변에 있는 링크를 추적한 후, 이제 혼란의 일부가 어디서 왔는지 알 수 있습니다.Miku의 답변은 단일 괄호를 사용하지만 링크에 연결된 코드 조각은 괄호를 사용하지 않습니다.단지:

the_world_is_flat=true
if $the_world_is_flat; then
  echo 'Be careful not to fall off!'
fi

두 코드 스니펫은 동일한 방식으로 동작하지만 괄호는 후드 아래에서 진행되는 내용을 완전히 변경합니다.

다음은 Bash가 각 사례에서 수행하는 작업입니다.

괄호 없음:

  1. 수를확을 합니다.$the_world_is_flat "true".
  2. " " " " 분석을 합니다."true"명령으로서
  3. 을 찾아 합니다.true 제공 또는 기명)/bin/trueBash 버전에 따라 다름).
  4. 의종 코비다니교합를의 종료 를 비교해 .true명항(과 0. 에서 종료 을 나타내고 에서 종료 코드 0은 성공을 대부분의 셸에서 종료 코드 0은 성공을 나타내고 다른 모든 항목은 실패를 나타냅니다.
  5. 가 0이었으므로, 이를 합니다.if명서의세.then.

대괄호:

  1. 수를확을 합니다.$the_world_is_flat "true".
  2. 분석합니다. 이은 " " " " 입니다.string1 = string2.=연산자는 bash의 문자열 비교 연산자입니다.그래서...
  3. 다에대 문열비수행에 대해 문자열 ."true"그리고."true".
  4. 네, 두 줄이 같았기 때문에 조건부 값이 맞습니다.
  5. 합니다.if명서의세.then

브래킷이 없는 코드는 작동합니다. 왜냐하면true명령은 성공을 나타내는 종료 코드 0을 반환합니다.로 묶은 는 작동하는데,그는 괄로묶코작드다동의 입니다. 왜냐하면 값이$the_world_is_flat문자열 리터럴과 동일합니다.true의 에.=.

요점을 정확히 파악하기 위해 다음 두 가지 코드 조각을 고려하십시오.

이 코드(루트 권한으로 실행되는 경우)는 컴퓨터를 재부팅합니다.

var=reboot
if $var; then
  echo 'Muahahaha! You are going down!'
fi

이 코드는 "Nice try"만 출력합니다.reboot 명령은 호출되지 않습니다.

var=reboot
if [ $var ]; then
  echo 'Nice try.'
fi

업데이트(2014-04-14) 간의 차이에 대한 댓글 질문에 답하기=그리고.==AFAIK, 차이는 없습니다.==▁a입의 Bash 입니다.=제가 본 바로는, 그들은 모든 상황에서 정확히 동일하게 작동합니다.

하지만, 제가 특별히 말하고 있는 것은=그리고.==는 문열비연 사용자산에 됩니다.[ ]또는[[ ]]가 제안하는 것은 아닙니다.=그리고.==bash의 모든 곳에서 교환할 수 있습니다.

를 들어, 여러분은 변수 을 예를들어, 변할을사수로 할 수 .==를 들어, 를들어예와 같은var=="foo"(기술적으로 당신은 이것을 할 수 있지만, 그 가치는.var▁▁be 될 것입니다."=foo"왜냐하면 배시는 보지 않기 때문입니다.==여기 연산자, 그것은 보고 있습니다.=연산자 값 (누락) 가,▁(▁the▁by다니▁followed표.="foo"그것은 단지."=foo").

또한, 록비.=그리고.==호환 가능합니다. 이러한 테스트가 작동하는 방식은 내부에서 사용하는지 여부에 따라 다르다는 것을 명심해야 합니다.[ ]또는[[ ]]피연산자의 인용 여부에 대해서도 마찬가지입니다.자세한 내용은 Advanced Bash Scripting Guide: 7.3 기타 비교 연산자에서 확인할 수 있습니다(자세한 내용은 아래로 스크롤하여=그리고.==).

산술식을 사용합니다.

#!/bin/bash

false=0
true=1

((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true

출력:

진실의
이 아닌

긴 이야기 요약:

Bash에는 불란이 없습니다.

true그리고.false

Bash에는 비교 및 조건 측면에서 부울식이 있습니다.즉, Bash에서 선언하고 비교할 수 있는 것은 문자열과 숫자입니다.바로 그겁니다.

당신이 보는 곳 어디를 보든지true또는falseBash에서는 종료 코드에만 사용되는 문자열이거나 명령/빌트인입니다.

이 구문...

if true; then ...

기본적으로...

if COMMAND; then ...

는 휘권이있는입니다.true0이 될 때마다 입니다. 이 명령어는 0을 반환합니다.true그리고.false는 Bash 내장형이며 때로는 해당 종료 코드만 반환하는 독립 실행형 프로그램이기도 합니다.


if..then..fi

대괄호를 할 때test명령입니다. 해당 구성의 종료 코드에 의존합니다.을 명심하세요.[ ]그리고.[[ ]]또한 명령/내장되어 있습니다.그래서...

if [[ 1 == 1 ]]; then echo yes; fi

에 해당하는

if COMMAND; then echo yes; fi

리고그고.COMMAND에 에기가 .[[ 변수 매개변사하여용를수▁the▁param1 == 1 ]]

if..then..fi구성은 단지 통사적인 설탕입니다.동일한 효과를 위해 항상 이중 앰퍼샌드로 구분된 명령을 실행할 수 있습니다.

[[ 1 == 1 ]] && echo yes

을 할 때true그리고.false "" "" " " " " " " " 라는합니다."true"또는"false"테스트 명령까지.다음은 예입니다.

믿거나 말거나, 이러한 조건들은 모두 동일한 결과를 내고 있습니다.

if [[ false ]]; then ...
if [[ "false" ]]; then ...
if [[ true ]]; then ...
if [[ "true" ]]; then ...

TL;DR; 항상 문자열 또는 숫자와 비교

미래의 독자들에게 이것을 분명히 하기 위해, 저는 항상 인용문을 사용하는 것을 추천합니다.true그리고.false:

if [[ "${var}" == "true" ]]; then ...
if [[ "${var}" == "false" ]]; then ...
if [[ "${var}" == "yes" ]]; then ...
if [[ "${var}" == "USE_FEATURE_X" ]]; then ...
if [[ -n "${var:-}" ]]; then echo "var is not empty" ...

하지 마

# Always use double square brackets in bash!
if [ ... ]; then ...
# This is not as clear or searchable as -n
if [[ "${var}" ]]; then ...
# Creates impression of Booleans
if [[ "${var}" != true ]]; then ...
# `-eq` is for numbers and doesn't read as easy as `==`
if [[ "${var}" -eq "true" ]]; then ...

아마도요.

# Creates impression of Booleans.
# It can be used for strict checking of dangerous operations.
# This condition is false for anything but the literal string "true".
if [[ "${var}" != "true" ]]; then ... 

오래 전에, 우리가 가진 모든 것은sh부울은 다음의 관례에 의존하여 처리됩니다.test로▁where치▁programtest인수 없이 실행된 경우 잘못된 종료 상태를 반환합니다.

이를 통해 거짓으로 설정되지 않은 변수와 임의의 값으로 설정된 변수를 참으로 생각할 수 있습니다. 오은늘,.test는 Bash에 기본 제공되며 일반적으로 한 문자 별칭으로 알려져 있습니다.[(또는 고인돌이 기록한 것처럼, 그것이 없는 껍질에 사용할 실행 파일):

FLAG="up or <set>"

if [ "$FLAG" ] ; then
    echo 'Is true'
else
    echo 'Is false'
fi

# Unset FLAG
#    also works
FLAG=

if [ "$FLAG" ] ; then
    echo 'Continues true'
else
    echo 'Turned false'
fi

인용 규칙 때문에 스크립트 작성자는 compound 명령을 사용하는 것을 선호합니다.[[흉내는을 흉내 test 공백이 있는 는 따옴표로 묶을 . 를 사용할 수 . 공백이 있는 변수는 따옴표로 묶을 필요가 없습니다. 사용할 수 있습니다.&&그리고.||이상한 우선 순위를 가진 논리 연산자이며, 항 수에 대한 POSIX 제한이 없습니다.

예를 들어, FLAG가 설정되어 있고 COUNT가 1보다 큰 숫자인지 확인하려면:

FLAG="u p"
COUNT=3

if [[ $FLAG  && $COUNT -gt '1' ]] ; then
    echo 'Flag up, count bigger than 1'
else
    echo 'Nope'
fi

공백, 0 길이 문자열 및 null 변수가 모두 필요할 때와 스크립트가 여러 셸과 함께 작동해야 할 때 이 항목이 혼동될 수 있습니다.

불리언을 꾸며서 미래의 독자들에게 함정을 남기는 대신, 참과 거짓보다 더 나은 가치를 사용하는 것은 어떨까요?

예:

build_state=success
if something-horrible; then
  build_state=failed
fi

if [[ "$build_state" == success ]]; then
  echo go home; you are done
else
  echo your head is on fire; run around in circles
fi

셸 스크립트에서 부울 변수를 선언하고 사용하려면 어떻게 해야 합니까?

다른 많은 프로그래밍 언어와 달리, Bash는 변수를 "유형"으로 분리하지 않습니다. [1]

그래서 답은 꽤 명확합니다.Bash에 부울 변수가 없습니다.

그러나:

선언문을 사용하여 값 할당을 변수로 제한할 수 있습니다.[2]

#!/bin/bash
declare -ir BOOL=(0 1) # Remember BOOL can't be unset till this shell terminates
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}

# Same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"

r할 수 있습니다.declare그리고.readonly변수가 읽기 전용임을 명시적으로 나타내는 데 사용됩니다.목적이 명확했으면 좋겠습니다.

저의 발견과 제안은 다른 게시물들과 조금 다릅니다.저는 기본적으로 "부울어"를 어떤 "일반적인" 언어로도 사용할 수 있다는 것을 알게 되었습니다. "후프 점프"가 제안하지 않아도...

할 필요가 전혀 없습니다.[]또는 명시적 문자열 비교...저는 여러 리눅스 배포판을 시도했습니다.Bash, Dash 및 BusyBox를 테스트했습니다.결과는 항상 똑같았습니다.저는 원래 상위 투표된 게시물이 무슨 말을 하는지 잘 모르겠습니다.어쩌면 시대가 변해서 그게 전부일까요?

변수를 다음으로 설정하는 경우true이후 조건부 내에서 "파생형"으로 평가됩니다.로 합니다.false그리고 "음성"으로 평가됩니다.아주 직설적입니다!유일한 경고는 정의되지 않은 변수도 처럼 평가된다는 것입니다!대부분의 언어에서 그렇듯 반대로 했다면 좋겠지만, 그것이 요령입니다. 부울을 true 또는 false로 명시적으로 초기화하기만 하면 됩니다.

왜 이런 식으로 작동합니까?그 대답은 두 가지입니다.셸에서 true/false는 실제로 "오류 없음" 대 "오류"(예: 0 vs 기타)를 의미합니다.true/false는 값이 아니라 셸 스크립팅의 입니다!두 번째 점에 대해, 실행true또는false속한 을 해당합니다. 선 위 서 는 에 블 반 값 해 값 설 으 로 합 정 니 다 당 을 환 의 록 있 는 사 용 가 자 니 합 ▁on 설 다 ▁a ▁you ▁the 정 ▁by ▁line ▁for , ▁block ▁value ' 선 ▁value ▁sets ▁to ▁thatfalse는 "오류가 발생했습니다"의 선언이며, 여기서 진정한 의미는 "오류가 발생했습니다"입니다.변수 할당과 함께 사용하면 변수로 "반환"됩니다.정의되지 않은 변수는 다음과 같이 평가됩니다.true하지 않음"을 동일하게 로. 0 "오류가 발생하지 않음"을 나타냅니다.

아래의 Bash 행 및 결과 예제를 참조하십시오.확인하고 싶으면 직접 테스트해 보세요...

#!/bin/sh

# Not yet defined...
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=true
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=false
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

수확량

when set to
it evaluates to true
when set to true
it evaluates to true
when set to false
it evaluates to false

휴대용 운영 체제 인터페이스

저는 여기서 핵심 포인트인 휴대성을 놓치고 있습니다.그래서 제 헤더에 POSIX가 들어있습니다.

기본적으로 투표된 모든 답변은 바시에 특화된 것을 제외하고는 모두 정답입니다.

기본적으로 휴대성에 대한 정보를 더 추가하고 싶습니다.


  1. [그리고.]와같대호괄과 같은 [ "$var" = true ]필요하지 않으며, 당신은 그것들을 생략하고 사용할 수 있습니다.test직접 명령:

    test "$var" = true && yourCodeIfTrue || yourCodeIfFalse
    

    중요한 참고:이것은 천천히 사용되지 않고 여러 문장을 결합하는 것이 더 어려워지기 때문에 더 이상 추천하지 않습니다.

  2. 그 단어들이 무엇인지 상상해보세요.true그리고.false직접 테스트해 보십시오.

    echo $(( true ))
    
    0
    
    echo $(( false ))
    
    1
    

    그러나 인용문 사용:

    echo $(( "true" ))
    
    bash: "true": syntax error: operand expected (error token is ""true"")
    sh (dash): sh: 1: arithmetic expression: expecting primary: ""true""
    

    다음도 마찬가지입니다.

    echo $(( "false" ))
    

    셸은 문자열 외에는 해석할 수 없습니다.인용문 없이 적절한 키워드를 사용하는 것이 얼마나 좋은지에 대한 아이디어를 얻고 있기를 바랍니다.

    하지만 아무도 그것을 이전 답변에서 말하지 않았습니다.

  3. 이것은 무엇을 의미합니까?음, 몇 가지.

    • 숫자처럼 . 즉, 당은부울키실숫취자즉것급는합니다에익야져숙.true=0그리고.false=1 모든 은 0으로 처리됩니다.false.

    • 변수는 숫자로 처리되므로 변수를 정의하는 경우 다음과 같이 말합니다.

      var_bool=true
      echo "$var_bool"
      
       true
      

      다음을 사용하여 반대 값을 생성할 수 있습니다.

      var_bool=$(( 1 - $var_bool ))  # same as $(( ! $var_bool ))
      echo "$var_bool"
      
      1
      

    당신이 직접 볼 수 있듯이, 그 껍질은 인쇄합니다.true처음 사용하는 문자열이지만, 그 이후로 모두 번호를 통해 작동합니다.0을대하는표를 true또는1을대하는표를 false각각 다음과 같다.


마지막으로, 당신이 그 모든 정보로 무엇을 해야 하는지.

  • 첫째, 한 가지 좋은 습관은 할당하는 것입니다.0true;1false.

  • 두 번째로 좋은 습관은 변수가 0과 같지 않은지 테스트하는 것입니다.

    if [ "$var_bool" -eq 0 ]; then
         yourCodeIfTrue
    else
         yourCodeIfFalse
    fi
    

많은 프로그래밍 언어에서 부울 유형은 정수의 하위 유형으로 구현됩니다.true 럼행다니합처럼 합니다.1그리고.false 럼행다니합처럼 합니다.0:

수학적으로, 부울 대수는 정수 산술 모듈 2와 유사합니다.따라서 언어가 기본 부울 형식을 제공하지 않는 경우 가장 자연스럽고 효율적인 해결책은 정수를 사용하는 것입니다.이것은 거의 모든 언어에서 작동합니다.예를 들어 Bash에서 다음 작업을 수행할 수 있습니다.

# val=1; ((val)) && echo "true" || echo "false"
true
# val=0; ((val)) && echo "true" || echo "false"
false

남자 bash:

((설명)

식은 ARCHATIC EVALUATION에서 아래에 설명된 규칙에 따라 평가됩니다. 식의 값이 0이 아닐 경우 반환 상태는 0이고, 그렇지 않을 경우 반환 상태는 1입니다.이것은 정확히 "표현"을 허용하는 것과 같습니다.

구문과 관련하여, 이것은 제가 부울 논리를 일관되고 제정신으로 관리하기 위해 사용하는 간단한 방법론입니다.

# Tests
var=
var=''
var=""
var=0
var=1
var="abc"
var=abc

if [[ -n "${var}" ]] ; then
    echo 'true'
fi
if [[ -z "${var}" ]] ; then
    echo 'false'
fi

# Results
# var=        # false
# var=''      # false
# var=""      # false
# var=0       # true
# var=1       # true
# var="abc"   # true
# var=abc     # true

다음과 같은 # false

true로 은 (이방법을 하여) true로 설정하는입니다.var=1반로대,var=''.

참조:

-n0이 입니다. var 문 이 0 닌 입 니 true 다

-z입니다. var는 0이면 true입니다.

Bill Parker는 투표에서 부결되었습니다. 왜냐하면 그의 정의가 일반적인 코드 규약과 반대이기 때문입니다.일반적으로 true는 0으로 정의되고 false는 0이 아닌 것으로 정의됩니다. 1은 false에 대해 작동하며 9999 및 -1도 마찬가지입니다.함수 반환 값 - 0은 성공이고 0이 아닌 모든 값은 실패입니다.죄송합니다, 저는 아직 투표를 하거나 그에게 직접 회신할 거리의 신뢰도를 가지고 있지 않습니다.

Bash는 이제 단일 대괄호 대신 이중 대괄호를 습관으로 사용할 것을 권장하며, Mike Holt가 제공한 링크를 통해 작동 방식의 차이를 설명합니다. 7.3 기타 비교 연산자

첫째로, 하는나,-eq숫자 연산자이므로 코드를 가지고 있습니다.

#**** NOTE *** This gives error message *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

정수 식을 예상하여 오류 문을 실행합니다.이는 두 매개변수 모두 정수 값이 아니므로 두 매개변수 모두에 적용됩니다.그러나 이중 괄호를 두드리면 오류 문이 발행되지 않고 잘못된 값이 생성됩니다(가능한 순열의 50%).0 - eq true] = 성공으로 평가되지만, 0 - eq false] = 성공으로 평가되는데, 이는 잘못된 것입니다(흠흠..수치로 내장된 것은 어떻습니까?).)

#**** NOTE *** This gives wrong output *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then

잘못된 출력을 제공하는 다른 조건부 순열도 있습니다.기본적으로 변수를 숫자 값으로 설정하고 참/거짓 내장과 비교하거나 변수를 참/거짓 내장으로 설정하고 숫자 값과 비교하는 모든 항목(위에 나열된 오류 조건 제외)입니다.하고 또한거변참짓/기제본공설로정을 사용하여 입니다.-eq그러니 피하세요-eq부울 비교의 경우 숫자 값을 사용하지 않도록 합니다.다음은 잘못된 결과를 제공하는 순열의 요약입니다.

# With variable set as an integer and evaluating to true/false
# *** This will issue error warning and not run: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

# With variable set as an integer and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then


# With variable set as an true/false builtin and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then

자, 이제 무엇이 효과가 있는지 알아보겠습니다.비교와 평가 모두에 참/거짓 기본 제공 기능을 사용합니다(Mike Hunt가 언급했듯이 인용문으로 묶지 마십시오).그런 다음 단일 또는 이중 등호(= 또는 ==)와 단일 또는 이중 대괄호([ ] 또는 [ ])를 사용합니다.개인적으로, 저는 이중등호를 좋아합니다. 왜냐하면 그것은 제가 타이핑하는 것을 좋아하기 때문에 다른 프로그래밍 언어의 논리적 비교와 큰따옴표를 떠올리게 하기 때문입니다.다음과 같은 작업이 가능합니다.

# With variable set as an integer and evaluating to true/false
# *** These statements will work properly: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then

바로 그겁니다.

불리언을 사용하는 또 다른 방법은 값의 비어 있음을 테스트하는 것입니다.이를 통해 짧은 테스트를 수행할 수 있다는 장점이 있습니다.

first=1  # A true value
second=   # A false value

[ -n "$first" ]  && echo 'First var is true'
[ -z "$first" ]  && echo 'First var is false'
[ -n "$second" ] && echo 'Second var is true'
[ -z "$second" ] && echo 'Second var is false'

출력:

First var is true
Second var is false

은 bash: bash의 입니다.[[ -n $one ]]

(나 자신의) 바보짓에 대한 나의 레시피:

# setting ----------------
commonMode=false
if [[ $something == 'COMMON' ]]; then
    commonMode=true
fi

# using ----------------
if $commonMode; then
    echo 'YES, Common Mode'
else
    echo 'NO, no Common Mode'
fi

$commonMode && echo 'commonMode is ON  ++++++'
$commonMode || echo 'commonMode is OFF xxxxxx'

변수가 설정되지 않은 경우에 대한 Dennis Williamson의 우려를 해결하는 miku의 원래 답변에 대한 개선 사항은 다음과 같습니다.

the_world_is_flat=true

if ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

그리고 변수가 다음과 같은지 테스트합니다.false:

if ! ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

변수에 잘못된 내용이 있는 다른 경우에 대해, 이것은 프로그램에 공급되는 외부 입력의 문제입니다.

외부 입력을 신뢰하기 전에 유효성을 검사해야 합니다.그러나 이러한 유효성 검사는 해당 입력이 수신될 때 한 번만 수행해야 합니다.

Dennis Williamson이 제안하는 처럼 변수를 사용할 때마다 프로그램의 성능에 영향을 줄 필요는 없습니다.

"boolean"과 에는 "합니다.! &&또는|| 기술적으로에). ) 으로 변환됩니다. 대부분의 해석된 언어에서는 (거의) 모든 유형이 다음과 같은 작업에서 자동으로 부울 형식으로 변환됩니다.! &&또는||.

부울은 항상 부울 연산과 함께 작동합니다. Bash 서이러작아다같습다니과오음니은업한에아(▁(▁in다오ations)입니다."" 부근에$var매우 중요합니다!:

[[ $var ]] - check if var is true
[[ ! $var ]] - check if var is false
[[ $var1 || $var2 ]] - var1 or var2
[[ $var1 && $var2 ]] - var1 and var2

[[ $var ]]다음과 같은 경우에만 false입니다.var=''(또는 설정 해제).따라서 bash에서 변수의 올바른 'false' 값은 "(빈 문자열)뿐입니다.할 수 는 var=1을 1을 합니다). true 모 든 값 var=1 다을는니합다선을호만지있는저는수른의택을할사프항합용니var▁을▁formers,▁always(▁you다▁program▁but▁1true▁any사용상▁1합니다는1

참고: 의 경우var='false'부울 검사의 변수는 입니다.Bash 문자열에서'false'는 사실입니다(다른 모든 언어와 동일).Python,은 Bash Bash 와 Python에서 는 PHP 유 차 Bash 니입 점다에차이의의은서점일한이또▁▁in▁that▁the에▁perl다rence▁between▁one▁bash니입점▁bash▁diffe,의▁is이서▁and▁php,,차는의,▁bash▁php▁only▁bash▁perl또일점한와이은유▁e라는 것입니다.0또한 사실입니다.그러나 다시 말하지만, Bash에는 부울 연산이 있으며, 그것들은 다른 모든 해석된 언어와 마찬가지로 작동합니다. 단,0바시에서는 사실입니다.

현을 사용하는 것은 완전히 비합리적입니다.'true'그리고.'false'Bash에서 부울 대체물로 사용됩니다.그것은 파이썬, 펄, PHP에서 같은 이상한 개념을 사용하는 것과 같습니다.(바시에서도) 더 느리게 작동하고 다른 언어로는 아무도 그것을 하지 않지만, 바시에는 그것이 좋은 해결책이라고 생각하는 많은 코더들이 있습니다. 으로 이상한 비교 에서 부울 직접 . Bash에서 부울 연산을 직접 사용하지 않을 이유가 없습니다.$var == 'true'또는$var == 'false'.

다시, Bash의 부울 대체물은 다음과 같습니다.

var=''  # false
var=1   # true (actually any non-empty string)

또한 Bash에서 부울식 체크를 직접 사용하는 것이 부울식 체크를 수행하는 가장 빠른 방법입니다.다른 모든 공사는 훨씬 더 느리게 진행될 것입니다.

추신: "오래된" 스타일의 "부글부글" 체크는 다음과 같습니다.a=true; if $a; then ...완전 바보야, 이유는:

  1. 상황에서 직접 사용할 수 없습니다.[[ ]]
  2. 그들은 역할을 합니다.eval변수에 저장된 bash 코드입니다.이 그것이 생각이라고 한다면, 도 쓰지 제발;) , 만약당신이그좋생생면다각한고라이각마제요세발쓰어지프떤도로램그음것이은),;)

추신: 만약$var설정이 해제될 수 있으며 매우 유용하게 사용할 수 있습니다.set -u그냥 대체합니다.$var${var-}를 들어, 예를 들어, 기호입니다.[[ ${var-} ]](또한: 아니요)""코드 실행 속도가 중요합니다!)

다음은 저에게 효과적인 간단한 예입니다.

temp1=true
temp2=false

if [ "$temp1" = true ] || [ "$temp2" = true ]
then
    echo "Do something." 
else
    echo "Do something else."
fi

여기 짧은 손의 구현이 있습니다.if true.

# Function to test if a variable is set to "true"
_if () {
    [ "${1}" == "true" ] && return 0
    [ "${1}" == "True" ] && return 0
    [ "${1}" == "Yes" ] && return 0
    return 1
}

예 1

my_boolean=true

_if ${my_boolean} && {
    echo "True Is True"
} || {
    echo "False Is False"
}

예 2

my_boolean=false
! _if ${my_boolean} && echo "Not True is True"

저는 기존의 답변들이 혼란스럽다는 것을 발견했습니다.

개인적으로, 저는 단지 C처럼 보이고 작동하는 것을 원합니다.

이 스니펫은 프로덕션에서 하루에도 여러 번 작동합니다.

snapshotEvents=true

if ($snapshotEvents)
then
    # Do stuff if true
fi

그리고 모두를 행복하게 하기 위해, 저는 다음을 테스트했습니다.

snapshotEvents=false

if !($snapshotEvents)
then
    # Do stuff if false
fi

그것도 잘 작동했습니다.

$snapshotEvents변수의 값 내용을 평가합니다.그래서 당신은 그것이 필요합니다.$.

당신은 괄호가 꼭 필요한 것은 아닙니다. 도움이 될 뿐입니다.

다음은 Bash에서 "Boolean" 값을 테스트하는 다양한 방법에 대한 속도 테스트입니다.

#!/bin/bash
rounds=100000

b=true # For true; b=false for false
type -a true
time for i in $(seq $rounds); do command $b; done
time for i in $(seq $rounds); do $b; done
time for i in $(seq $rounds); do [ "$b" == true ]; done
time for i in $(seq $rounds); do test "$b" == true; done
time for i in $(seq $rounds); do [[ $b == true ]]; done

b=x; # Or any non-null string for true; b='' for false
time for i in $(seq $rounds); do [ "$b" ]; done
time for i in $(seq $rounds); do [[ $b ]]; done

b=1 # Or any non-zero integer for true; b=0 for false
time for i in $(seq $rounds); do ((b)); done

그것은 다음과 같은 것을 인쇄할 것입니다.

true is a shell builtin
true is /bin/true

real    0m0,815s
user    0m0,767s
sys     0m0,029s

real    0m0,562s
user    0m0,509s
sys     0m0,022s

real    0m0,829s
user    0m0,782s
sys     0m0,008s

real    0m0,782s
user    0m0,730s
sys     0m0,015s

real    0m0,402s
user    0m0,391s
sys     0m0,006s

real    0m0,668s
user    0m0,633s
sys     0m0,008s

real    0m0,344s
user    0m0,311s
sys     0m0,016s

real    0m0,367s
user    0m0,347s
sys     0m0,017s

shFlags를 사용할 수 있습니다.

수 합니다.DEFINE_bool

예:

DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");

명령줄에서 다음을 정의할 수 있습니다.

sh script.sh --bigmenu
sh script.sh --nobigmenu # False
[[ "$x" == 'true' || "$x" -ne 0 ]] && ...

충분히 단순하고 종속성이 없습니다.

는 Bash와 문제를 혼동합니다.[,[[,((,$(( 타기.

모두가 서로의 코드 공간을 밟고 있습니다.제 생각에 이것은 대부분 역사적인 것 같습니다. Bash가 가장해야 했던 곳입니다.sh가끔.

대부분의 경우, 저는 그냥 방법을 선택하고 그것을 고수할 수 있습니다.이 있습니다. (할 수 것이 좋습니다.).내 실제 스크립트에서).

TRUE=1; FALSE=0

그러면 사용할 수 있습니다.((...))이와 같이 테스트할 산술 연산자.

testvar=$FALSE

if [[ -d ${does_directory_exist} ]]
then
    testvar=$TRUE;
fi

if (( testvar == TRUE )); then
    # Do stuff because the directory does exist
fi
  1. 당신은 훈육을 받아야 합니다.당신의.testvar " 으로설정합야니다해다음합"로 설정해야 합니다.$TRUE또는$FALSE항시에

  2. ((...))대조군, 당신은 이전의 것이 필요하지 않습니다.$더 쉽게 읽을 수 있게 해줍니다.

  3. 사용할 수 있습니다((...))$TRUE=1그리고.$FALSE=0숫자 값.

  4. ▁a를 사용해야 한다는 것입니다.$가끔:

    testvar=$TRUE
    

    별로 예쁘지도 않은.

완벽한 해결책은 아니지만, 그런 테스트가 필요한 모든 경우를 커버합니다.

대안 - 함수 사용

is_ok(){ :;}
is_ok(){ return 1;}
is_ok && echo "It's OK" || echo "Something's wrong"

함수를 정의하는 것은 직관적이지 않지만 반환 값을 확인하는 것은 매우 쉽습니다.

언급URL : https://stackoverflow.com/questions/2953646/how-can-i-declare-and-use-boolean-variables-in-a-shell-script

반응형