sh 하나의 명령으로 AND 및 OR

sh 하나의 명령으로 AND 및 OR

한 줄의 코드에서 3가지 조건을 확인하려고 하는데 막혔습니다.

기본적으로 다음 코드를 작성해야 합니다.

만약에

문자열 1은 문자열 2와 같지 않습니다.

그리고

문자열 3은 문자열 4와 같지 않습니다.

또는

부울 1 = 참

그 다음에

"조건 충족 - 코드 실행 중..."이 표시됩니다.

의견에서 요청한 대로 질문을 더 명확하게 만들기 위해 예제를 업데이트했습니다.

#!/bin/sh

string1="a"
string2="b"
string3="c"
string4="d"
bool1=true

# the easy-to-read way ....
if [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ; then
    echo "conditions met - running code ..."
fi

if $bool1 ; then
    echo "conditions met - running code ..."
fi

# or the shorter way ...
[ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] && echo "conditions met - running code ..."

$bool1 && echo "conditions met - running code ..."

위의 코드는 두 번 실행될 수 있습니다. 처음 두 조건이 충족되면 다시 실행되고, 세 번째 조건이 충족되면 다시 실행됩니다. 이것은 나에게 필요한 것이 아닙니다.

이 예제의 문제점은 두 개의 서로 다른 "에코" 호출이 포함되어 있다는 것입니다. (참고: 실제 코드에서는 에코가 아니지만 아이디어를 얻을 수 있습니다.) 3가지 조건부 검사를 하나의 명령으로 결합하여 코드 중복을 줄이려고 합니다.

지금 당장 고개를 저으며 화면을 향해 “그건 바로”라고 소리치는 사람들이 있을 거라 확신합니다.아니요당신은 그렇게 않았다 방법! "

이것을 중복으로 표시하기 위해 기다리는 사람들이 있을 수도 있습니다... 음,내가 봤다하지만 내가 읽은 답변을 통해 이 작업을 수행하는 방법을 알아낼 수 있다면 저주받을 것입니다.

누군가 나를 깨달을 수 있습니까? :)

답변1

이것은 작동합니다:

if    [ "$string1" != "$string2" ] \
   && [ "$string3" != "$string4" ] \
   || [ "$bool1" = true ]; then
    echo "conditions met - running code ...";
fi;

또는 { ;}가독성을 높이고 향후 유지 관리를 쉽게 하기 위해 둘러싸여 있습니다.

if { [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ;} \
   || [ "$bool1" = true ] ; then
    echo "conditions met - running code ...";
fi;

지침:

  1. 부울 변수와 같은 것은 없습니다..
  2. 중괄호 끝에는 세미콜론( { somecmd;}) 이 필요합니다..
  3. &&||평가 하고왼쪽에서 오른쪽으로위 - &&보다 우선합니다|| 오직 안에서만 (( ))그리고[[..]]

&&[[ ]]더 높은 우선순위는 다음과 같은 증명 에서만 발생합니다 . 생각하다 bool1=true.

그리고 [[ ]]:

bool1=true
if [[ "$bool1" == true || "$bool1" == true && "$bool1" != true ]]; then echo 7; fi #1 # Print 7, due to && higher precedence than ||
if [[ "$bool1" == true ]] || { [[ "$bool1" == true && "$bool1" != true ]] ;}; then echo 7; fi # Same as #1
if { [[ "$bool1" == true || "$bool1" == true ]] ;} && [[ "$bool1" != true ]] ; then echo 7; fi # NOT same as #1
if [[ "$bool1" != true && "$bool1" == true || "$bool1" == true ]]; then echo 7; fi # Same result as #1, proved that #1 not caused by right-to-left factor, or else will not print 7 here

그리고 [ ]:

bool1=true
if [ "$bool1" == true ] || [ "$bool1" == true ] && [ "$bool1" != true ]; then echo 7; fi #1, no output, due to && IS NOT higher precedence than ||
if [ "$bool1" == true ] || { [ "$bool1" == true ] && [ "$bool1" != true ] ;}; then echo 7; fi # NOT same as #1
if { [ "$bool1" == true ] || [ "$bool1" == true ] ;} && [ "$bool1" != true ]; then echo 7; fi # Same as #1
if [ "$bool1" != true ] && [ "$bool1" == true ] || [ "$bool1" == true ]; then echo 7; fi # Proved that #1 not caused by || higher precedence than &&, or else will not print 7 here, instead #1 is only left-to-right evaluation

답변2

&&조건식 끝에 사용하는 것은 이전 명령(첫 번째 인수)이 상태 0(전통적으로 프로그램의 성공 코드로 간주됨)을 반환하는 경우 후속 명령(두 번째 인수)을 실행한다는 의미입니다. 또한 $bool1거기에 입력하는 내용은 독립적이므로 Bash는 해당 값을 실행할 명령이나 프로그램의 이름으로 해석합니다. 달성하려는 것은 다음을 [사용하여 수행되는 조건식 평가인 것 같습니다.

if [ "$string1" != "$string2" ]  && [ "$string3" != "$string4" ] || [ $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi

내장된 "and", -a및 "or",,, -o연산자를 사용하는 이전 코드를 볼 수 있지만 이는POSIX 사양그리고 명확하게 정의되지 않았습니다.

if [ "$string1" != "$string2" -a "$string3" != "$string4" -o $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi

ksh예를 들어 에서 파생된 셸을 사용하는 경우 bash내장 테스트 연산자를 사용할 수 있습니다 [[.

[[ "$string1" != "$string2" && "$string3" != "$string4" || $bool1 -ne 0 ]] && echo "conditions met - running code ..."

부울 값은 정수로 표시되므로 -ne여기서는 "같지 않음" 정수 표현식 테스트를 사용할 수 있습니다. 작동 방식을 보여주는 스크립트는 다음과 같습니다.

#!/bin/bash

string1="Hello"
string2="Hello"
string3="Hello"
string4="Hello"
bool1=1

if [ "$string1" != "$string2" ]  && [ "$string3" != "$string4" ] || [ $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi

exit 0

관련 정보