&&와 ||의 혼란스러운 사용 연산자


93

나는 /etc/rc.d/init.d/sendmail파일을 통해 감추고 있었고 (이것은 거의 사용되지 않았지만 시험을 위해 공부하고 있음을 알고 있습니다), 나는 연산자 &&||연산자에 대해 약간 혼란스러워했습니다 . 나는 다음과 같은 문장에서 사용될 수있는 곳을 읽었습니다.

if [ test1 ] && [ test2 ]; then
     echo "both tests are true"
elif [ test1 ] || [ test2 ]; then
     echo "one test is true"
fi

그러나이 스크립트는 다음과 같은 한 줄 문장을 보여줍니다.

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0

이들은 테스트를 기반으로 응답을 이끌어 내기 위해 &&and ||연산자를 사용하는 것처럼 보이지만 이러한 연산자의 특정 용도에 관한 문서를 파헤칠 수는 없었습니다. 이 특정 상황에서 이들이 무엇을하는지 설명 할 수 있습니까?

답변:


141

&&왼쪽의 종료 상태가 0 인 경우에만 오른쪽 이 평가됩니다 (예 : true). ||반대입니다. 왼쪽 종료 상태가 0이 아닌 경우에만 오른쪽을 평가합니다 (즉, false).

[ ... ]리턴 값이있는 프로그램으로 간주 할 수 있습니다 . 내부 테스트가 true로 평가되면 0을 리턴합니다. 그렇지 않으면 0이 아닌 값을 반환합니다.

예 :

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!

추가 메모 :

당신이 할 경우 which [, 당신은 볼 수 [실제로 프로그램을 가리 않습니다! 일반적으로 스크립트에서 실행되는 것은 아닙니다. type [실제로 무엇이 실행 되는지 확인하십시오. 프로그램을 사용하고 싶다면 다음과 같이 전체 경로를 지정하십시오 /bin/[ 1 = 1.


6
"X 또는 Y"가 표시되면 X를 테스트합니다. 사실 인 경우 이미 "X 또는 Y"에 대한 답을 알고 있으므로 (Y), Y를 테스트 할 필요가 없습니다. "X 또는 Y"에 대답하면 Y를 테스트해야합니다. "X 및 Y"가 표시되면 X를 테스트합니다. 거짓 인 경우 이미 "X 및 Y"에 대한 답을 알고 있으므로 (거짓) Y를 테스트 할 필요가 없습니다. X가 true이면 "X 및 Y"가 true인지 확인하기 위해 Y를 테스트해야합니다.
David Schwartz

2
"왼쪽이 0을 반환하는 경우"대신 "왼쪽 ​​명령의 종료 상태가 0 인 경우"라고 씁니다. 나는 출력과 종료 상태와 같은 모호한 비트가 모두 "반환 값"으로 간주 될 수있다 "수익"을 찾을 수
글렌 잭맨

뿐만 아니라 당신은 "수 생각 [ ... ] 이 많은 경우에, 프로그램으로" 입니다 . 일반적으로 파일 /bin/[또는에 /usr/bin/[있습니다.
LS

5
C 프로그래머는이 혼란을 발견 할 것입니다. 0은 거짓을 의미합니다 ... 셸 스크립트에서 0은 참을 의미합니다 ...
Calmarius

언급 할 수있는 또 다른 방법 testif또는 대신입니다 [. 그리고 if [if test산재 것으로 보인다 [test뚜렷한 이유도 까닭에. Fedora x86_64의 공급 업체 라이브러리에 대한 config.sitetest 와 같이 가끔 표시됩니다 .

59

내 치트 시트는 다음과 같습니다.

  • "A; B"A의 성공에 관계없이 A를 실행 한 다음 B
  • "A && B"A가 성공하면 B를 실행하십시오.
  • "A || B"A가 실패하면 B를 실행하십시오.
  • "A &"백그라운드에서 A를 실행하십시오.

JavaScript 작업에서 보여지는 흥미로운 람다 미적분학이 있습니다 (변수를 순서대로 정의). "(일명 TRUE) 왼쪽" (a => b => a). "오른쪽 (일명 거짓)" (a => b => b). 다음, "A B" "" (a => b => (() => b())(a())). "A && B" "없는 경우 (언제)" (a => b => a()(() => right)(b)). "A || B" "그렇지 않으면 if (unless)"없이 (a => b => a()(b)(() => right)). "a && b || c" "ifThenElse" (a => b => c => (unless(when(a)(b))(c))()).
Dmitry

1
bash에서 left는 0 / 빈 문자열과 비슷하고 right는 다른 모든 것입니다.
Dmitry

28

@ Shawn-j-Goff의 대답을 위에서 확장 &&하면 논리 AND이며 ||논리 OR입니다.

Advanced Bash 스크립팅 안내서 의이 부분을 참조하십시오 . 사용자 참조 링크의 일부 내용은 다음과 같습니다.

&& AND

if [ $condition1 ] && [ $condition2 ]
#  Same as:  if [ $condition1 -a $condition2 ]
#  Returns true if both condition1 and condition2 hold true...

if [[ $condition1 && $condition2 ]]    # Also works.
#  Note that && operator not permitted inside brackets
#+ of [ ... ] construct.

|| 또는

if [ $condition1 ] || [ $condition2 ]
# Same as:  if [ $condition1 -o $condition2 ]
# Returns true if either condition1 or condition2 holds true...

if [[ $condition1 || $condition2 ]]    # Also works.
#  Note that || operator not permitted inside brackets
#+ of a [ ... ] construct.

11

내 경험으로는 && 및 || if 문을 한 줄로 줄입니다.

/root/Sample.txt라는 파일을 찾고 있다고 가정하면 일반적인 반복은 다음과 같습니다.

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi

이 6 개의 줄을 한 줄로 줄일 수 있습니다.

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"

변수를 설정하거나 파일 등을 만들기 위해 몇 가지 반복을 실행할 때 수명이 더 쉽고 스크립트가 한 줄 if 함수를 사용하여 더 매끄럽게 보이지만 단점은 단일 반복에서 여러 명령을 구현하는 것이 조금 더 어려워진다는 것입니다 기능을 사용할 수 있습니다.


이것은 멋지다. objc 코드를 상기시킵니다 (a == b)? val = 1 : val = 2;
GeneCode

"&"로 백그라운드에서 프로세스를 실행하려고 할 때이 명령을 어떻게 사용할 수 있습니까? ./someScript.sh & && echo 'ok' || echo 'ko'
Katie

4

"짧은 절단"이라는 개념이 있습니다.

(expr1 && expr2)평가 될 때 - "true"로 expr2평가 된 경우에만 평가됩니다 exp1. expr1AND expr2가 모두 참 (expr1 && expr2)이어야하기 때문입니다. expr1"false"로 평가 되면 이미 "flase" expr2이므로 평가 되지 않습니다 (바로 가기) (expr1 && expr2).

다음을 시도하십시오-파일 F1이 존재하고 파일 F2이 존재하지 않는다고 가정하십시오 .

( [ -s F1 ] && echo "File Exists" )  # will print "File Exists" - no short cut
( [ -s F2 ] && echo "File Exists" )  # will NOT print "File Exists" - short cut

비슷하게 ||(또는)-그러나 짧은 절단은 반대입니다.


5
논리는 일반적으로 "단락"이라고합니다. 나는 "단축"이라는 문구를 본 적이 없다. 참고 문헌을 찾는 데 도움이되도록 이것을 언급합니다.
LS

-1

Shawn J. Goff의 답변 예제는 정확하지만 설명은 그 반대입니다. 확인해주십시오:

&&의 오른쪽은 왼쪽의 종료 상태가 NONZERO 인 경우에만 평가됩니다. || 왼쪽 출구 상태가 ZERO 인 경우에만 오른쪽을 평가합니다.


3
쉘의 경우 종료 코드 0true로 평가 되므로 결과 의 왼쪽에 0이 아닌 종료 코드가 &&있으면 전체 표현식에서 false 를 리턴한다는 것을 알고 있습니다.
카운터 모드

1
귀하의 답변이 아니기 때문에 누군가가 수정 사항을 승인하지 않았습니다. 당신이 어떤 대답이 틀렸다고 생각한다면 그 답을 내려 놓고 의견을 남기십시오. 변경이 필요하다고 생각되면 의견을 남겨야합니다. 편집은 답변의 의미를 변경하지 않는 문법, 서식 및 철자 오류를 수정하기위한 것입니다.
techraf

1
@countermode 미안하지만, 그렇습니다. 리눅스에서 0 = false 및 0이 아닌 = true라고 생각했습니다 (C 및 다른 많은 언어 / 환경 / 플랫폼 에서처럼). 오해에 대해 사과드립니다.
Try2Help
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.