`if $cmd ; 정확히 어떻게요? 그러면 $cmd fi`는 `$cmd && $cmd`와 다른가요?

`if $cmd ; 정확히 어떻게요? 그러면 $cmd fi`는 `$cmd && $cmd`와 다른가요?

다른 사람에게 답장으로매우 좋은질문 나는 다음과 같이 주장합니다.

POSIX 사양을 읽어보면 둘 중 하나를 사용하는 구문 분석 관점과 차이가 없습니다.

POSIX 지정 &&||목록은 다음과 같습니다.복합 명령이는 구성된 단순 명령을 실행하기 전에 전체 목록을 읽고 구문 분석해야 함을 의미합니다. POSIX는 또한 명령을 지정합니다확장이 허용되지 않음||OR종료 상태가 0인 다른 명령을 따르는 경우 . 예약어 뒤에 오는 명령이 &&||다른 명령으로 쉽게 그룹화될 수 있다고 생각되면 { command || ( command ; list) ; }또는 목록의 각 분기를 &&||자체적으로 만드십시오.복합 명령.

그러나 POSIX는 또한 if...;then...;else...fi구성의 각 분기에 고유한 속성이 있음 을 지정합니다.복합 명령그래서:

if compound-list
then
    compound-list
[elif compound-list
then
    compound-list] ...
[else
    compound-list]
fi

이것if 화합물 목록exit상태가 0이면 실행되어야 합니다.then 화합물 목록실행되고 명령이 완료됩니다.

then...else...or 뒤의 문자열과 예약어 뒤의 문자열을 로 만드는 것이 이 사양이다.복합 명령그 자체로 뿐만 아니라간단한 명령이는 쉘의 파서가 올바르게 작동하려면 명령과 구분 기호를 나타내야 함을 의미합니다.

따라서 기본적으로 then ' '같은 이유로 작동하지 않습니다.

function()
sh: line 2: syntax error: unexpected end of file 

...아니요 – 그건 말도 안 돼요.

알아요...

[ -e doesntexist ] && $((i=1)) ; echo $i

\n... 내 답변에서 지적한 사양으로 인해 모든 부작용이 단락되고 단 하나의 ewline만 생성됩니다. 결과는...

if [ -e doesntexist ] 
    then $((i=1))
fi
echo $i

……그것은 동일합니다.

그런데 솔직히 제가 if...fi사용을 거의 안해서 뭔가 잘못 읽은건지 잘 모르겠어서 설명이 틀렸다는 댓글이 달리거나, 추가적으로 궁금한 점이 있으면 그냥 물어보곤 합니다. 답변을 삭제하고 다음 질문으로 대체했습니다. 내가 어떻게 틀렸나요? 어떻게 다릅니까?

답변1

단순한 경우만 sum 으로 &&표현할 수 있습니다 ||. 이 if구조는 더 일반적입니다. (필요한 경우 블록을 구분하기 위해 중괄호를 올바르게 사용한다고 가정) if CONDITION; then FOO; fi동일 하지만 일단 (또는 )이 발생하면 일반적으로 더 이상 불가능합니다.CONDITION && FOOelseelif

if CONDITION; then FOO; else BAR; fi

같지 않음

CONDITION && FOO || BAR

true 이면 CONDITION두 구성이 모두 실행됩니다 FOO. FOOfalse 인 경우 if생성을 건너뛰고 BAR생성 && … ||이 수행됩니다 BAR.

아니요, 이 문제를 해결하는 데 이를 사용할 수 없습니다 CONDITION && { FOO; true; } || BAR. 그러면 복합 명령이 이 경우 true이면 true를 반환 CONDITION하고 false를 반환하게 됩니다.FOOif CONDITION; then FOO; else BAR; fi

이는 의미상의 차이입니다. 또한 가독성도 있습니다. &&중첩된 사용으로 인해 ||빠르게 해독하기 어려워집니다. 사실, 동일한 명령에 이 두 연산자를 사용하는 것을 권장하지 않습니다. 특히 두 연산자 모두 셸에서 동일한 우선 순위를 갖는 반면 C와 Perl 및 Ruby를 포함한 대부분의 다른 C 언어에서는 우선 순위가 다르다는 점을 고려하면 더욱 그렇습니다.

답변2

if testlist; then else ...fi그리고 testlist && thenlist || elselist일반적으로 말해서 그것들은 동일하지 않습니다. 차이점은 구성 시 if및 중 하나만 실행된다는 것입니다. 다른 경우에는 종료 코드에 따라 달라지며 차단될 수도 있습니다.thenlistelselistthenlisteliflist

true따라서 목록이 실행되도록 한 테스트 목록과 동일한 종료 코드를 갖도록 선택한 결과 목록의 끝에 추가(예를 들어) 해야 합니다 .

if true; then
  echo true
  test -e doesntexist
else
  echo false
fi

이는 코드 블록의 종료 코드를 결정하여 무시할 수 있습니다 &&. ||바꾸다

true && { echo true; test -e doesntexist; } || echo false

당신은해야합니다

true && { echo true; test -e doesntexist; true; } || echo false

일생

if test -e exists; then
  echo true
elif test -e doesntexist
  echo elif
else
  echo false
fi

~ 할 것이다

test -e exists && { echo true; true; } ||
  { test -e doesntexist && { echo elif; true; } || echo false; }

관련 정보