서브쉘과 if 블록의 차이점

서브쉘과 if 블록의 차이점

차이점은 무엇입니까?

set -e;
./create-git-tag.sh || {
   echo 'Could not create git tag.'
   exit 1;
}

그리고

set -e;
if ! ./create-git-tag.sh; then 
    echo 'Could not create git tag.'
    exit 1;
fi

if 블록이 하위 쉘을 생성하지 않아 if 블록이 입력되기 전에 종료되는 것 같아요. 기능적으로는 동일해 보이지만 동작에 차이가 있나요?

답변1

중괄호는 { }하위 쉘을 생성하지 않지만 괄호는 다음을 수행합니다.

큰 타격(1)

(목록)

목록은 서브쉘 환경에서 실행됩니다.

{목록;}

list는 현재 쉘 환경에서만 실행됩니다.

따라서 if명령문이나 양식 모두 ... || { }하위 쉘을 생성할 가능성이 없습니다.

서브쉘 환경가능한( )중괄호 대신 괄호를 사용하여 생성된 경우. 첫 번째 명령이 ||0이 아닌 상태를 반환하는 경우에만 (즉../create-git-tag.sh 실패).

사용하는 경우 set -e모든 양식은 동일한 동작을 나타냅니다(테스트 명령이 실패하면 쉘이 즉시 종료됩니다). 하지만 뒤에서 괄호는 하위 쉘을 생성합니다(이 예에서는 쓸모없어 보입니다).

만약에set -e 아니요를 사용하여 하위 쉘을 생성한다는 것은 ( )하위 쉘이 종료되지만 호출 쉘은 계속 진행됨을 의미합니다. 후속 명령은 계속 실행됩니다.

모든 경우에 echo-exit 명령 체인(및 괄호로 묶인 관련 서브셸)은 테스트 명령이 실패한 경우에만 입력됩니다. 그러나 조건부 논리를 만드는 요점은 무언가가 실패할 수도 있고 그렇지 않을 수도 있다는 것입니다. 이는 질문에 대한 표현이 이해되지 않는 부분입니다.

if 블록이 하위 쉘을 생성하지 않으므로 if 블록이 입력되기 전에 종료되는 것 같습니다.

차단하면일단 "입력"되면 테스트 명령을 실행하여 다음에 수행할 작업을 결정합니다.

개인적으로 나는 이 if문장이 읽기 쉽고 스크립트에서 사용하는 것을 더 선호한다고 생각합니다. 쉘을 "대화식으로" 사용할 때 운영자 &&||나는 in을 사용할 수 있습니다.if

답변2

내 이해는 두 경우 모두 동일하며 exit스크립트를 실행하는 셸 인스턴스가 종료된다는 것입니다.

두 버전 모두 하위 쉘을 생성하지 않습니다. 이를 입증하기 위해 다음 실험을 고려하십시오.

$ cat version1
#!/bin/bash

set -e

x=7

ls /tmp/does/not/exist &> /dev/null || {
    x=42
}

echo $x


$ ./version1
42
$ cat version2
#!/bin/bash

set -e

x=7

if [ ! ls /tmp/does/not/exist &> /dev/null ]; then
    x=42
fi

echo $x

$ ./version2
42

(다음 버전에 표시된 대로) 로 { }변경 하면 하위 쉘이 생성됩니다. 따라서 내부 수정은 호출 셸에 영향을 주지 않습니다 .version1()x( )x

$ cat version3
#!/bin/bash

set -e

x=7

ls /tmp/does/not/exist 2> /dev/null || (
    x=42
)

echo $x

$ ./version3
7

관련 정보