if 조건의 대괄호 : 공백없이 구문 오류가 발생하는 이유는 무엇입니까?


17

아래 스크립트를 사용하여 일년 중 이틀에 스크립트를 실행할 때 이틀 뒤로 이동하고 매월 첫 번째와 두 번째 날을 확인하고 이틀 뒤로 이동합니다.

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

하지만 내 잘못은 아래 오류 메시지가 나타납니다.

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found

1
주어진 답변은 정확합니다. 뒤에 공백이 필요합니다 [. 또한, elif성명서를 살펴보십시오 . 정리하는 데 도움이됩니다. 또한 if 문 뒤의 세미콜론은 필요하지 않지만 잘못된 것은 아니며 이상한 것입니다.
Shawn J. Goff

@ ShawnJ.Goff 다음 줄 ( if [ ... ]; then) 을 연결하면 필요합니다 .
goldilocks

@ goldilocks, 예, 그게 내가 선호하는 스타일입니다. 특이한 이유는 그가 그렇게하지 않기 때문입니다.
Shawn J. Goff

답변:


27

[은 메타 문자도 아니고 제어 연산자도 (예약어도 아니고 ]) 동일 하므로 주위에 공백이 필요합니다. 그렇지 않으면 쉘 명령 "을보고" [01=01]명령 대신 [별도의 매개 변수 01, =, 01,와 ]. 각 연산자와 피연산자는 [명령에 대해 별도의 인수 여야 하므로 연산자 주위에도 공백이 필요합니다.

if [ "$month" = "01" ]

[$month="01"]$month또는 의 문자와 일치하는 와일드 카드 패턴 "01입니다. 일치하지 않으면 홀로 남습니다.

닫는 대괄호 뒤에 세미콜론이 있으면 세미콜론은 항상 별도의 토큰의 일부이므로 공백이 필요하지 않습니다.

if [ "$month" = "01" ]; then

bash (및 ksh 및 zsh) 이중 괄호 구문도 마찬가지입니다.

하나 이상의 조건

조건을 결합하는 두 가지 방법이 있습니다.

  1. 이내에 [

  2. 별도의와 [명령과 함께 &&또는||

대괄호로 그룹화하는 것이 아마 더 쉽습니다 [.

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

첫 번째는 신뢰할 수 없으므로 피해야합니다 (예 :로 시도하십시오 month='!'). 안전한 문자열 (있는 경우)을 먼저 사용하면 이상한 가변 컨텐츠 문제를 피할 수 있습니다. 나에 의해 사용 [[/ ]]대신 [/ ]:

if [ "01" = "$month" -a "01" = "$day" ]

[$ month = "01"] && [$ day = "01"]의 경우 월 값 == 일 값과 같은 if의 두 조건을 일치시키는 방법; 01 && 01 true를 예상하고 조건 아래에 인쇄하거나 else 문으로 이동
Kumar1

@AshokSanganahalli 나는 대답을 확장했다.
Hauke ​​Laging 2016 년

1
[-a/ -o를 사용하지 않는 경우 POSIX 호환 쉘에서 항상 신뢰할 수 있습니다. -a/-oover 를 사용하면 이점이 없습니다 &&/||. 나는 그것의 사용을 분명히하지 않을 것입니다. 즉, 참고 [[POSIX 없습니다.
Stéphane Chazelas

4

그것을 쓰는 또 다른 방법 :

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac

1
case성명서 +1 둘 이상인 경우 elif사용 중일 수 있습니다 case.
HalosGhost

-1

그래서 이것은 당신의 대답입니다.

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

따라서 대괄호와 변수 / 값 사이에 "공백"을 넣어야합니다.


아니요, GUESS입니다. 스크립트가 연 2 일에 시작될 때 스크립트가 2 일 뒤로 이동하고 매월 1 일과 2 일을 확인하고 2 일 뒤로 이동하도록 요청 했으므로 [$ month = "01"] && [$ day = "01"] 우리는 "01"월과 첫날 "01"true를
맞추고,

1
@AshokSanganahalli : 이것이 어떻게 관련되어 있는지 모르겠지만, 대괄호와 값 사이에 "공백"이 없어 IF 조건이 작동하지 않습니다
Neven

@AshokSanganahalli 기술 수준이 높은 사람들은 힌트를 적어도 시도하지 않고 분명히 더 잘 이해하고있는 사람들의 수정에 대해 이의를 제기하는 것은 좋은 생각이 아닙니다. 당신의 추측이 옳다면 여기에 묻지 않아도됩니다.
Hauke ​​Laging 지난

4
-1에 대한 변수의 사용이 아닌 인용 ==대신 표준을 =.
Stéphane Chazelas

2
질문에는 bash 태그가 없습니다. 표준 [aka test명령 의 등식 비교 연산자 는 =입니다. [테스트의 경우 할당을 수행하지 않으므로 명확하게 할 필요가 없습니다. 일부 [구현 ==은 표준에 대한 확장으로 지원 하지만 전부는 아닙니다. Bourne 쉘의, ash의, posh[의 또는 /bin/[예를 들어 일부 시스템의하지 않습니다. ==님이 추가 ksh했습니다. 새로운 (( ... ))구조 에서 동일한 연산자와 일관성을 유지한다고 가정합니다 (= 및 ==이지만 표준은 없음)
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.