$? if 문에서


12
function foo {
   (cd $FOOBAR;
   <some command>
   if [$? -ne 0]
   then
      echo "Nope!"
   else
      echo "OK!"
   fi
   )
}

위와 같은 함수를 작성하여 내 .bashrc 파일에 넣으려고합니다. 파일을 소스로 실행 한 후 다음을 얻습니다.

총 시간 : 51 초
-bash : [1 : 명령을 찾을 수 없습니다
!

누군가 내가 잘못한 것을 이해하도록 도울 수 있습니까?


4
경우 테스트 $?IS가와 0이 if문 무의미 if명령을 예상하고 있는 경우 명령이 리턴 말했다 0, 그것은 블록의 코드를 실행합니다. 그래서 if true; then echo hello; fi명령이 에코합니다 안녕하세요 이후 true반환 0.
llua

1
@llua 무의미하지 않습니다. 명령문 의 ( ) 명령 이 아닌 $?마지막 파이프 라인 의 상태를 보유합니다 . 예는 성공 여부 를 테스트하는 것 입니다. 당신과 같은 작업을 수행 할 수 있습니다 하고 있지만, 긴, 읽을 줄은 비교 할 수 있습니다 . 같은 인수는 간다test[ifsome command&&||if [ $? -eq 0 ]if some command
bonsaiviking

@ bonsaiviking 나는 무엇을 $?확장하고 있는지 잘 알고 있습니다. 나는 test사용중인 점이 없다는 것을 지적하고 있습니다 . 왜냐하면 if some command하나의 진술과 두 개의 별도 진술이 있기 때문에 같은 일을합니다. 명령이 이미 길면 문자를 세 개 더 추가해도 '읽을 수없는'것이 더 '읽을 수없는'것이 아닙니다.
llua

답변:


33

상기 후 공간을 추가 [하고, 다른를하기 전에 ]:

function foo {
   (cd $FOOBAR;
   <some command>
   if [ $? -ne 0 ]
   then
      echo "Nope!"
   else
      echo "OK!"
   fi
   )
}

[쉘 내장이며,이 명령은 같다 echo, read, expr... 그것은 뒤에 공백을 필요로하고 일치가 필요합니다 ].

쓰기가 [ $? -ne 0 ]실제로 호출하는 [과 4 개 매개 변수를 제공합니다 : $?, -ne, 0,와 ].

참고 : 오류가 발생했다는 [1: command not found사실 $?은의 값을 의미합니다 1.


1
방금 Linux VM에서 귀하의 답변이 올바른지 확인했습니다.
samiam

[에 대한 링크입니다 test뿐만 아니라
리키 빔

2
대부분의 쉘에서 @RickyBeam은 [쉘 내장 /usr/bin/[이며 거의 사용되지 않습니다.
Patrick

20

아니면 $?완전히 건너 뛸 수 있습니다. 명령이 cmd인 경우 다음이 작동합니다.

function foo {
   (cd $FOOBAR;
   if cmd
   then
      echo "OK!"
   else
      echo "Nope!"
   fi
   )
}

6

변수를 사용하기 전에 반환 값을 변수에 할당하는 것이 좋습니다

retval="$?"
if [ $retval -ne 0 ]

반환 값을 재사용 할 수 있습니다. 예를 들어 if ... elif ... else ... 문에서.


-1 : 다음에 공백을 잊었습니다 (공백 [없이 구문 오류가됩니다 bash). 오류를 편집하고 수정하면 실행 취소됩니다.
samiam

그렇습니다. 나는 그것을 고쳤다.
Abdul

@samiam 마지막 코멘트가 당신을
향한

4
:) 답을 조금 넓힐 수 있습니까? 왜 좋은 습관입니까? 어떤 종류의 오류를 피할 수 있습니까?
terdon

1
@terdon $?나중에 스크립트를 편집 할 때 명령과 $?검사 사이에 줄을 넣으면 중단되기 때문에 직접 사용하는 것은 좋지 않습니다 .
samiam

3

명령 $?에 대한 인수로 [명령 을 사용하려는 유일한 이유 는 ( 명령 [의 조건 부분에서 명령이 실행 되는지 여부에 관계없이 if) 다음과 같이 특정 리턴 상태를 구별하려고 할 때입니다.

until
  cmd
  [ "$?" -gt 1 ]
do
  something
done

모든 사람들을위한 구문은 if, while, until... 문이다

if cmd-list1
then cmd-list2
else cmd-list3
fi

성공 cmd-list2여부 cmd-list1에 관계없이 실행 됩니다 cmd-list3.

[ "$?" -eq 0 ]명령은 어떤 조합입니다. 이 설정 $?경우 0으로 $?0이며, $?그 이외의 영점 인 경우 0이 아닌.

cmd실패 했을 때 무언가를 실행하려면 다음과 같습니다.

if ! cmd
then ...
fi

일반적으로 $?어떤 값이 true또는을 의미하는지 혼자 알지 않아도됩니다 false. 특정 값을 구별해야하거나 나중에 저장 해야하는 경우 (예 : 함수의 반환 값으로 반환) 유일한 경우는 위에서 말한 것입니다.

f() {
  cmd; ret=$?
  some cleanup
  return "$ret"
}

또한 따옴표없는 변수를 남겨 두는 것은 split + glob 연산자라는 것을 기억하십시오. 여기에서 해당 연산자를 호출하는 것은 의미가 없으므로 다음과 같아야합니다.

[ "$?" -ne 0 ]

아니 [ $? -ne 0 ], 홀로 [$? -ne 0 ](만 호출 할 것이다 [경우 명령 $IFS의 첫 번째 문자를 포함 할 일이 $?).

또한 함수를 정의하는 Bourne 방식 function-name()은 명령 앞에 붙는 것 입니다. 즉, 제외 쉘과 같은 모든 Bourne 씨의 사건 bashyash(와 최신 버전의 posh유일한 복합 명령 (화합물 명령 인 허용) {...}(...)또는 같은 것들 for...done, if...fi...

function foo { ... }은 IS ksh함수 정의 문법. 여기서 사용하고 싶은 이유는 없습니다.

코드를 이식 가능하게 (POSIX) 작성할 수 있습니다.

foo() (
  cd -P -- "$FOOBAR" || return # what if the cd failed!
  if
    <some command>
  then
    echo 'OK!'
  else
    echo 'Nope!'
  fi
)

또한 cd없는 -P특수한 의미 ( ..다른 명령과 다르게 구성 요소 를 포함하는 경로를 처리 )가 있으므로 혼동을 피하기 위해 스크립트에 포함하는 것이 좋습니다.

(함수가 반환하는 false경우는 cd실패가 아닌 경우 <some command>실패).


1

아래 명령이 한 줄로 원하는 모든 것을 할 것이라고 믿습니다.

(( verify = $?!=0?'Nope!':'OK!' ))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.