변수가 존재하는지 확인하고 busybox의 문자열과 비교하는 방법은 무엇입니까?

변수가 존재하는지 확인하고 busybox의 문자열과 비교하는 방법은 무엇입니까?

나는 다음과 같은 것을 사용하고 싶다

if [[ ! -z "$ENV" && $ENV == 'production' ]]; then echo "production"; else echo "dev"; fi

하지만 BusyBox에서는 작동하지 않습니다 :(

sh: 1: [[: not found

비지박스로 들어가는 IF 문에서 AND 또는 OR의 조합이 작동하지 않는 것 같습니다.

답변1

[[...]]bash및 에서도 지원되는 Korn 쉘 구성이지만 zsh표준 구성은 아닙니다 sh(그리고 다른 쉘에서는 지원되지 않습니다).

busybox shash이는 POSIX 사양의 하위 집합 (POSIX 로케일 내에서 대부분 호환됨)을 구현하며 sh특히 이 확장이 아닌 확장이 거의 없습니다.

2019년 편집. 사용 및 구축 시 busybox ash는 이제 [[...]]ksh뿐만 아니라 .ASH_TESTASH_BASH_COMPATyash

그럼에도 불구하고 스크립트를 작성할 때는 shPOSIX 사양을 준수해야 합니다 . sh사용된 스크립트는 [[...]]호출되거나 ksh명시 적 bash으로 zsh호출되어야 합니다. bash또한 POSIX sh 와 주로 호환되지만 더 많은 확장 기능(이 확장 기능 포함)을 갖춘 쉘입니다.

시험엑스비어 있지 않으면 production의미가 없습니다. 만약에엑스== production그렇다면 분명히 비어 있지 않습니다.

문자열 비교를 위해 POSIX 셸과 유틸리티를 사용하면 여러 가지 옵션이 있으며, 이 경우 가장 확실한 옵션은 다음과 같습니다.

  • [유틸리티는라고도 하며 test일반적으로 셸에 내장되어 있습니다.

      if [ "$var" = production ]; then
        echo PROD
      fi
    
  • 구조 case:

      case $var in
        production) echo PROD;;
        "") echo EMPTY;;
        *) echo non-PROD;;
      esac
    

이제 변수가 다음과 같은지 확인하고 싶을 수도 있습니다.놓다(null이 아닌 것과 반대로) 역참조하기 전에 해당 nounset옵션이 활성화된 경우( set -u또는 set -o nounset또는 #! /bin/sh -ushe-bang 라인과 함께 사용), 그렇지 않으면 [ "$ENV" = production ]a가 설정되지 않은 경우 쉘이 종료됩니다. $ENV이렇게 하려면 다음을 수행해야 합니다.

if [ "${var+set}" = set ] && [ "$var" = production ]; then
  echo PROD
fi

-a [( AND 연산자는 더 이상 사용되지 않으며 신뢰할 수 없으므로 사용하지 않아야 합니다 .)

더 좋고 공식적인 방법은 다음과 같습니다.

if [ "${var-}" = production ]; then
  echo PROD
fi

nounset${var+string}트리거 되거나 확장되지 않습니다 ${var-string}. 변수가 설정되면 ${var-}콘텐츠로 확장되고, 그렇지 않으면 빈 문자열로 확장됩니다.$var

기타 참고사항:

$ENV특수 변수입니다 sh. 대화형으로 실행되면 초기화를 읽은 파일의 경로로 처리됩니다( ~/.bashrcfor 와 동일 bash). 다른 목적으로 사용하시면 안됩니다.

문자열 비교 사용 [ "x$var" = xproduction ]또는 수행을 제안하는 오래된 Unix 쉘 스크립팅 문헌을 찾을 수 있습니다 . 이는 aka 유틸리티의 일부 이전 버전에서 , 또는 와 같은 특정 값으로 인해 혼동되는 버그를 [ production = "$var" ]극복하기 위한 것입니다 . 최신 시스템에서는 이를 필요로 하지 않지만 아주 오래된 시스템의 경우 염두에 두어야 할 사항입니다. 어쨌든 이 구성에는 그런 문제가 없습니다.[test$var!(-ncase

문자열 비교를 수행할 수 있는 다른 POSIX 유틸리티로는 expr및 가 있습니다 awk.

 awk_equal() { awk 'BEGIN{exit(!(""ARGV[1] == ""ARGV[2]))}' "$1" "$2"; }
 expr_equal() { expr "x $1" = "x $2" > /dev/null; }

 if awk_equal "$var" production; then
   echo PROD
 fi
 if expr_equal "$var" production; then
   echo PROD
 fi

문자열 비교(그렇지 않으면 or 와 동일하게 처리됨 ) 를 얻고 같은 이유로 연산자 로서의 값에 문제가 발생 하지 않도록 하려면 ""값 앞에 with가 필요합니다 .awk1011e0xexprexpr

awkand expr(적어도 POSIXly) 의 경우 실제로는 그렇지 않습니다.평등연산자는 대신 두 피연산자가 동일한 정렬 순서를 갖는지 여부를 테스트합니다. 이는 반드시 동일한 것은 아닙니다. 예를 들어 내 시스템에서는 expr_equal ② ③②와 ③ 모두 정의된 정렬 순서가 없기 때문에 true가 반환됩니다. 일부 awk구현(예 gawk: mawk및 busybox)은 awkPOSIX 요구 사항을 무시하고 대신 간단한 바이트 간 비교를 수행합니다.

[어쨌든, 나는 당신이 여기 보다 이것을 선호할 어떤 타당한 이유도 생각할 수 없습니다 case.

답변2

이전 [구문을 사용할 수 있습니다

if [ -n "$ENV" -a "$ENV" = 'production' ]

-n(읽기가 더 쉽기 때문에 대신 사용하고 있지만 ! -z똑같습니다.)

또는 문자열에 값을 지정하여 이전 구문으로 단순화할 수 있습니다.

if [ "x$ENV" = 'xproduction' ]

마지막으로 -n테스트가 실제로 필요하지 않을 수도 있습니다.

if [ "$ENV" = 'production' ]

관련 정보