내 if 문이 부울 값을 거꾸로 해석하는 이유는 무엇입니까?

내 if 문이 부울 값을 거꾸로 해석하는 이유는 무엇입니까?

내 .zshrc에 있는 여러 기능의 출력이 매우 혼란스럽습니다.

function __isred {
  if [[ $(ps cax | grep redshift | wc -l) > 0 ]]
  then
    return 1
  else
    return 0
  fi
}

function __togred {
  if __isred
  then
    killall redshift
  else
    redshift &
  fi
} 

__isred의 아이디어는 redshift가 실행 중이면 true를 반환하고, 그렇지 않으면 false를 반환한다는 것입니다. echo를 사용하여 올바른 출력을 반환하는지 확인할 수 있습니다. 그러나 출력이 1이면 __togred의 if 문은 then 대신 else 블록으로 이동합니다. 여기서 뭔가 빠졌나요?

답변1

쉘 명령의 경우 종료 상태 0은 true/성공을 나타내고 다른 값은 false/실패를 나타냅니다(다양한 유형의 실패를 구별하려면 정확한 값을 사용하십시오). 애초에 정확한 종료 상태 값을 사용하는 것을 피하고 대신 falseor true명령을 사용하는 것이 좋습니다:

__isred() {
  if [[ $(ps cax | grep redshift | wc -l) > 0 ]]
  then
    true
  else
    false
  fi
}

이 시점에서 다음과 같이 할 수 있기 때문에 이것이 약간 어리석은 일이라는 것을 깨닫기 시작합니다.

__isred() [[ $(ps cax | grep redshift | wc -l) > 0 ]]

이는 [[ > ]]어휘 비교를 위한 것입니다. 여기서 수치 비교를 사용하는 것이 더 합리적입니다.

__isred() (( $(ps cax | grep redshift | wc -l) > 0 ))

그러나 실제로는 이러한 일이 한 번 이상 발생했는지 확인하려는 경우 발생 횟수를 계산할 필요가 없습니다.

__isred() { ps cax | grep -q redshift; }

그 정도면 충분합니다. grep정규식이 일치하면 성공이 반환됩니다.

이제 비표준 구문을 사용할 때 좀 더 이식성이 뛰어난 명령을 사용하여 이 작업을 보다 쉽고 안정적으로 수행 ps할 수 있습니다 .pgreppsgrep

__isred() { pgrep redshift > /dev/null; }

답변2

zsh매뉴얼 에서 :

if list then list [ elif list then list ] ... [ else list ] fi    
    The if list is executed, and if it returns a zero exit status, the then list is executed.
    Otherwise, the elif list is executed and if its status is zero, the then list is executed.
    If each elif list returns nonzero status, the else list is executed.

Unix 시스템에서는 관례적으로 반환 값 0이 성공을 나타냅니다. 이는 반직관적이지만 명령이 다양한 오류에 대해 서로 다른 반환 값을 사용할 수 있도록 허용하므로 의미가 있습니다.

관련 정보