"foo && bar || baz"는 bash의 "if foo; then bar; else baz"와 다르게 동작합니다.

"foo && bar || baz"는 bash의 "if foo; then bar; else baz"와 다르게 동작합니다.

제 생각에는

[ 1 -eq $1 ] && echo "yes" || echo "no"

처럼 행동하다

if [ 1 -eq $1 ]; then
    echo "yes"
else
    echo "no"
fi

그러나 이 스크립트를 실행하면 ( nocmd존재하지 않는 명령입니다)

#!/bin/bash

[ 1 -eq $1 ] && nocmd "yes" || echo "no"

매개변수 "1"에 대해 이상한 출력이 표시됩니다.

me@ubuntu:/tmp$ ./ddd.sh 0
no
me@ubuntu:/tmp$ ./ddd.sh 1
./sh.sh: line 3: nocmd: command not found
no

이것이 하는 일인 것 같습니다:

if [ 1 -eq $1 ]; then
    nocmd "yes"
    if [ $? -ne 0 ]; then
        echo "no"
    fi
else
    echo "no"
fi

괜찮으세요? 내가 뭐 놓친 거 없니?

답변1

전반적인 종료 상태 외에도 다음과 같이 작동합니다.

if
  ! { 
    [ 1 -eq $1 ] && nocmd "yes"
  }
then
  echo no
fi

존재하다:

A || B

B실패할 경우에만 실행됩니다 A. OR 연산자입니다.

귀하의 경우 Aiff는 성공적으로 실행됩니다 [ 1 -eq $1 ] && nocmd "yes"(AND 연산자). 이 경우의 종료 상태는 의 종료 상태가 됩니다. 즉, 실패하면 실행됩니다(성공한 경우에만 실행된다는 점을 기억하세요).nocmd[Anocmdecho no[nocmd "yes"nocmd[

이것은 x && y || z더러운 해킹입니다. 이러한 이유로 사용을 피하는 것이 가장 좋습니다. if/then/else 논리가 정말로 필요한 경우 if// 구성을 사용하세요. 및 둘 다 성공하지 않는 한 원하는 경우에만 사용하십시오.thenelsex && y || zzxy

일지라도:

cmd && echo OK || echo >&2 KO

특정 병리학적 조건 echo OK(예: 전체 파일 시스템의 파일로 이동하는 stdout)에서는 실패할 수 있으며 echo >&2 KO결국 실행될 수도 있습니다.

$ bash -c 'true && echo OK || echo KO >&2' > /dev/full
bash: line 0: echo: write error: No space left on device
KO

답변2

글쎄요, 실제로 일어나는 일은 이렇습니다( &&작동 방식은 이렇습니다 ||)

test 1 -eq $1
ret=$?
if [ $ret -eq 0 ]; then
    nocmd "yes"
    ret=$?
fi
if [ $ret -ne 0 ]; then
    echo "no"
fi

귀하의 경우, $1같지 않다면 1,또는 유효한 숫자가 아닙니다., 그러면 0이 아닌 값이 있고 $?첫 번째 값 if은 건너뛰고 두 번째 값은 if"no"를 인쇄합니다. $1같음 1이 실행 되면 nocmd "yes"0이 아닌 값이 반환되고 $?"no"도 에코됩니다.

답변3

누락된 것은 왼쪽-왼쪽 연관성에 대한 명령의 종료 상태에서 작동하는 것입니다 &&. ||여기에 가 있으며 명령 집합이 비성공적인 종료 상태를 반환하는 경우에만 some group of commands || echo "no"에코됩니다 .no

그 명령 세트는 무엇입니까? 첫 번째 경우에는 부분이 실패 [ 1 -eq "$1" ] && echo "yes"하면 [실패한 종료 상태로 처리되므로 [ 1 -eq "$1" ] && echo "yes"실행 echo "no"됩니다. 또한 왼쪽 연관성으로 인해 "$1"이 1일 때 성공을 반환 하고 존재하지 않는 쉘을 실행하게 하면 쉘은 오류 종료 상태를 반환하고 전체 그룹은 실패 종료 상태를 가지게 되므로 [ 1 -eq $1 ]` nocmd"아니요"가 에코됩니다.

대조적으로, if 문에서

if [ 1 -eq $1 ]; then
    echo "yes"
else
    echo "no"
fi

[어떤 경로를 택할지는 해당 구간의 출구 상태 에 따라 다릅니다 . 에코 실행 여부를 결정하는 역할 [ 1 -eq "$1" ] && echo "Yes" || echo "no"도 합니다 .echo "no"

두 번째 if 문 예제도 다릅니다.

if [ 1 -eq $1 ]; then
    nocmd "yes"
    if [ $? -ne 0 ]; then
        echo "no"
    fi
else
    echo "no"
fi

after는 논리 연산자 연결에서 일어나는 일에 의존하지 않습니다 echo "no". 물론 완료된 후에도 해당 섹션을 계속 실행할 수 있지만 여기에서는 해당 섹션의 종료 상태가 해당 섹션이 속한 전체 섹션과 그룹화되지 않습니다.elsenocmdecho "no"nocmdif

관련 정보