변수가 존재하고 같지 않은 경우 효율적으로 비교

변수가 존재하고 같지 않은 경우 효율적으로 비교

스크립트 구문 에 문제가 있습니다 sh. Asus 라우터용 스크립트를 작성했습니다. 스크립트가 완벽하게 작동합니다. 하지만 다음 줄이 있습니다.

if [[ "$OldIP" && "$StartIP" != "$OldIP" ]]; then echo OK; fi

와 가 동일하지 않은 echo OK경우에만 true(및 실행)여야 합니다 . 라인은 작동하지만 더 효율적으로 수행되는 것을 보고 싶습니다. 변수에 유효한 IP 주소가 포함되어 있습니다.$StartIP$OldIP

어떤 경우에는 $OldIP아무 것도 할당되지 않습니다(초기화되지 않음). 그러나 $OldIP존재하지 않는다면 이는 내 쉘에서 동일하지 않다는 것을 의미합니다!

$OldIP나는 그 줄이 존재하지 않는 경우 -> 다른지 테스트 -> 실행하는 것을 원하지 않습니다 echo OK.

$OldIP나는 그 줄이 a) 존재하지 않는 경우 -> 끝을 의미하기를 원합니다 . b) $OldIP존재하는 경우 -> 서로 다른지 테스트 -> 실행합니다 echo OK.

"$OLDIP" &&그래서 가능하다면 어떻게든 제거하고 싶습니다 . 실제 문제는 아닙니다. 배우고 싶습니다 :)

일종의 (그러나 작동하지 않습니다):

if [ [ "$OldIP" ] != "$StartIP" ]; then echo OK; fi

또는

if [ $OldIP != "$StartIP" ]; then echo OK; fi

내가 원하는 것을 수행하지만 다음과 같은 경우 불평합니다.기존 IP비어 있음(그러나 정상적으로 작동함)

~하는 동안

if [ "$OldIP" != "$StartIP" ]; then echo OK; fi

작동하지만 무시합니다.기존 IP비었다

답변1

엄밀히 말하면 값이 할당된 적이 없거나 할당된 변수는 존재하지 않습니다 unset. 값이 빈 문자열인 변수존재한다.

표준 매개변수 확장은 존재하는 경우 ${variable+value}문자열을 대체합니다 (설정 해제되거나 비어 있지 않음). 이는 다음과 같이 존재 여부를 테스트하는 데 사용될 수 있습니다.valuevariable

if [ "${OldIP+x}" = "x" ] && [ "$OldIP" != "$StartIP" ]; then
    # code
fi

OldIP에 존재하는지 테스트하려면 bash다음 테스트를 사용하세요 -v.

 if [[ -v OldIP ]] && [[ "$OldIP" != "$StartIP" ]]; then
     # code
 fi

이는 이전에 설정된 경우에만 (빈 문자열로 설정된 경우에도) $OldIP사이 의 문자열 비교를 수행합니다 . 테스트 에는$StartIPOldIP-v이름변수의.

답변2

나는 당신의 스크립트가 현재로서는 매우 효율적이라고 생각합니다. 당신은 확실히 이것에 많은 사이클을 소비하지 않습니다.

논리를 작성하는 또 다른 방법:

{ test -n "$OldIP" || test "$StartIP" != "$OldIP"; } && echo OK

이는 "OldIP가 설정되어 있거나 OldIP와 StartIP가 다른 경우 에코 OK입니다.

이는 로 읽을 수 있는 [또 다른 이름이라는 것을 기억하십시오 .test(1)man 1 test

편집: Gilles가 지적했듯이 ( ... )필요하지 않은 곳에 하위 쉘을 만들지 않도록 주의하십시오.

{ ... ; }새 셸을 실행하지 않고도 명령을 그룹화하는 데 사용할 수 있습니다.

간략한 참조:http://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html

답변3

이것은 귀하가 요청한 작업을 수행합니다.

[ "${OldIP:-"$StartIP"}" != "$StartIP" ] && echo "OK"

또한 다음과 같습니다(더 복잡함).

${OldIP:+false} || { [[ $OldIP != $StartIP ]] && echo "OK"; }

답변4

을 사용하는 경우 bash기본 대체를 사용할 수 있습니다.

[[ "${OldIP:=oldunset}" != "${StartIP?StartUnset" ]] && echo "OK"

구문은 변수가 설정되지 않았거나 null인 경우 ${var:-def}의 현재 값 $var또는 지정된 기본값(이 경우 )으로 평가됩니다. def변수의 값(있는 경우)은 변경되지 않습니다.

구문은 if is unset 또는 null ${var?message}이라는 메시지와 함께 오류 코드 1로 종료됩니다 .message$var

명시적으로 호환 가능한 테스트가 필요한 경우 test다음을 수행할 수 있습니다.

[ ! -z "$OldIP" -a "$OldIP" != "$StartIP" ] && echo "OK"

관련 정보