IF 테스트에서 너무 많은 경로 비교 매개변수를 반환함

IF 테스트에서 너무 많은 경로 비교 매개변수를 반환함

다음이 true를 반환해야 하는 경우 실제로 실패하고 bash 셸에서 실행될 때 인수가 너무 많다는 오류가 보고됩니다. 내 생각에는 큰따옴표가 포함된 모든 지침을 따랐지만 왜 그것이 내 인생에서 실패하는지 알 수 없습니다... 어떤 아이디어가 있습니까?

#!/usr/bin/bash
# These are the values in the environment
#echo ">"$PS_APP_HOME"<"  => >/app/psoft/app_85909<
#echo ">"PS_CUST_HOME"<"  => >/app/psoft/cust_85909<
#echo ">"$(pwd)"<"        => >/app/psoft/app_85909<

if [ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

답변1

[ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

[다음 매개변수를 사용하여 명령을 호출하십시오.

  1. 출력 pwd1,
  2. !=,
  3. 변수의 내용 PS_APP_HOME,
  4. ],
  5. -o,
  6. [,
  7. 다른 호출의 출력 pwd,
  8. !=,
  9. 변수의 내용 PS_CUST_HOME
  10. ].

]마지막 매개변수여야 하므로 첫 번째 매개변수를 [보면 혼란스러워집니다 .-o]

[-o더 이상 사용되지 않는 연산자 가 있습니다.또는, 그러나 이는 으로 사용하기 위한 것입니다 [ some-condition -o some-other-condition ]. 그러나 신뢰할 수 없는 테스트 표현식이 될 수 있으므로 사용해서는 안됩니다.

여기서는또는그것도 말이 안 돼요. 현재 작업 디렉터리는 무언가( $PS_APP_HOME)와 다른 것( ) 이 될 수 없으므로 $PS_CUSTOM_HOME둘 중 적어도 하나는 true입니다. 아마 당신이 말하는 것 같아요"$(pwd)" != "$PS_APP_HOME""$(pwd)" != "$PS_CUST_HOME"그리고바꾸다또는. 그래서:

  • 표준 구문을 사용하십시오.

    if [ "$PWD" != "$PS_APP_HOME" ] && [ "$PWD" != "$PS_CUST_HOME" ]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    [(첫 번째 명령이 성공하면 두 번째 명령을 실행합니다.&& 껍데기( [운영자는 아닙니다).

  • Korn과 유사한 구문:

    if [[ $PWD != "$PS_APP_HOME" && $PWD != "$PS_CUST_HOME" ]]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    또는

    if [[ ! ($PWD = "$PS_APP_HOME" || $PWD = "$PS_CUST_HOME") ]]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    [[...]]그 자체로 특별한 구조를 갖고 있는 것 입니다.조건식마이크로 언어 코드에는 &&(and)/ ||(or), !(not) 부울 연산자 도 있습니다.

다음을 사용할 수도 있지만 case:

case $PWD in
  ("$PS_APP_HOME" | "$PS_CUST_HOME") ;;
  (*) echo current directory is neither the APP nor CUST home
esac

$PWD비슷 $(pwd)하지만 다른 프로세스를 포크하고 해당 출력을 파이핑할 필요가 없으며 현재 작업 디렉터리에 대한 경로가 개행 문자로 끝나는 경우에도 여전히 작동한다는 점을 제외하면 더 효율적입니다. ²

위의 큰따옴표는 중요하므로 꼭 필요한 곳에만 넣었습니다(구성된 / 연산자에 대한 인수에서 분할+글로브를 방지 [하고 변수 값이 패턴이나 인수에서 처리되는 것을 방지하기 위해).!==[[...]]case모두인용된 확장은 해를 끼치지 않습니다.

어휘 비교를 수행하는 것 외에도 ksh/bash/zsh [[....]]및 대부분의 [구현( [내장 bash지원 연산자 포함) -ef은 두 파일이 동일한지(symlink 확인 후) 확인하므로 다음을 대신 사용할 수 있습니다 =.

if [[ ! (. -ef $PS_APP_HOME || . -ef $PS_CUST_HOME) ]]; then
  echo current directory is neither the APP nor CUST home
fi

또는 sh(대부분 sh)의 경우:

if [ ! . -ef "$PS_APP_HOME" ] && [ ! . -ef "$PS_CUST_HOME" ]; then
  echo current directory is neither the APP nor CUST home
fi

또한 여기에서는 현재 작업 디렉터리를 .참조하거나 참조하는 것이 $PWD보장 됩니다.$(pwd)

그런 식으로, 만약 $PWD그것이 /opt/app또는 /some/link/to/app이고 $PS_APP_HOME그것이 /opt/./app또는 /opt/foo/../app또는 /opt//app이라면, 그것은 여전히 ​​유효합니다.


¹ 후행 줄 바꿈을 제거하므로 현재 작업 디렉터리가 아닐 수도 있습니다.

² 일부 쉘에서는 $PWD현재 작업 디렉토리의 이름이 변경된 경우 오래된 정보가 제공될 수 있습니다. 그러나 이것은 일부 쉘에서도 마찬가지입니다. // pwd값을 출력 $PWD하고 업데이트만 합니다.cdpushdpopd

답변2

if [ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

이는 구문상 올바르지 않으므로 보고된 오류가 발생합니다.

이 작업을 테스트로 수행하려면 다음과 같이 하세요.

if [ "$(pwd)" != "$PS_APP_HOME" -o "$(pwd)" != "$PS_CUST_HOME" ]

또는 표현식을 완전히 분리하고 bash논리 OR을 처리하려는 경우:

if [ "$(pwd)" != "$PS_APP_HOME" ] || [ "$(pwd)" != "$PS_CUST_HOME" ]

관련 정보