둘 중에 뭘 더 좋아하시나요?
if ! [ ... ]; then
그리고
if [ ! ... ]; then
실제로 결과는 동일합니다. 선호하는 구문이 있습니까? 전자의 구문에서는 not이 쉘 내장으로 평가되는 반면, 후자의 구문에서는 not이 내장으로 평가됩니다 test
.
답변1
이식성 고려 사항.
키워드는 POSIX이지만 Bourne은 아니며 / 명령은 !
처음부터 !
지원됩니다 .[
test
그래서 .[ ! ... ]
! [ ... ]
-o
그렇지 않으면 더 이상 사용되지 않는 연산자 와 이항 연산자를 사용하지 않는 한 동일해야 합니다( 구현 시 오래된 / 파싱 버그를 -a
제쳐두는 경우 ).test
[
실제로 Bourne 쉘에서는 다음을 수행합니다.
if ! cmd1; then
cmd2
fi
당신은 이것을 해야 합니다:
if cmd1; then
:
else
cmd2
fi
(또는 를 사용하십시오 cmd1 || cmd2
. 그러나 궁극적으로 종료 상태가 달라질 수 있습니다).
set -o errexit
// set -e
트랩과 상호작용ERR
if
fi
@mosvy가 지적했듯이 / 문의 조건부 부분 외에 [ ! ... ]
와 사이의 또 다른 차이점은 후자가 ! [ ... ]
false를 반환하고 옵션이 켜져 있을 때 쉘이 종료되지 않는다는 것입니다.! [ ... ]
errexit
!
errexit
파이프에 적용하면 쉘이 파이프의 종료 상태를 다음과 같이 간주하므로 효과가 취소됩니다.상황. failing-pipeline || cmd
에도 동일하게 적용되거나 failing-pipeline && cmd
...
그리고 는 [ ! ... ]
명령 !
에 전달되는 일반 매개변수일 뿐입니다 [
. 궁극적으로 셸에 관한 한 이는 성공 또는 실패 종료 상태를 반환하는 명령 errexit
일 뿐입니다 .[
$ sh -ec '[ ! a = a ]; echo here'; echo "$?"
1
$ sh -ec '! [ a = a ]; echo here'; echo "$?"
here
0
if
이는 에 표시된 대로 while
// 문의 조건부 부분으로 이러한 명령이 실행되는 경우에는 적용 되지 않습니다.until
errexit
ERR
Korn의 포탄과 같은 함정 에도 동일하게 적용됩니다 .
$ ksh -c 'trap "echo OUCH" ERR; ! [ a = a ]'
$ ksh -c 'trap "echo OUCH" ERR; [ ! a = a ]'
OUCH
실제로 이는 [
거의 항상 조건으로 사용되며 적용되지 않는 경우( // 문 또는 뒤에 / 가 오는 경우 ) 에 errexit
적용되지 않기 때문에 아마도 차이가 없을 것입니다.if
while
until
&&
||
답변2
[ … ]
같음 test …
, 그래서 ! [ … ]
같음 ! test …
. 이는 명령의 결과를 부정한다는 의미입니다 test
. 이 경우에는 !
쉘 명령입니다.
info bash
예를 들어 "파이프라인" 섹션에서 다음을 수행 합니다 .
예약어 '!'가 파이프 앞에 오면 종료 상태는 위의 종료 상태에 대한 논리적 부정입니다.
반면에 는 [ ! … ]
을 의미합니다 test ! …
. 이는 테스트에서 표현식을 부정한다는 의미입니다. 또한보십시오 !
:man test
! EXPRESSION
EXPRESSION is false
그래서 다른 의미를 가질 수 있습니다. 복잡한 표현식이 있는 경우 부정은 표현식의 일부에만 작동할 수 있습니다.
당신이 좋아하는 것은 당신에게 달려 있습니다.