테스트 표현식에서 매개변수 확장이 가능합니까?

테스트 표현식에서 매개변수 확장이 가능합니까?

다음 표현식을 시도하면 bash이상한 오류 메시지가 나타납니다.

[: -lt: unary operator expected

먼저 함수 정의

some_func () {
  (( 3 + 5 ))
}

그리고 표현은

[ $(some_func) -lt 10 ] && true

-lt문제는 명령 대체 및/또는 산술 확장과 같은 연산자를 혼합하는 것 같아요 .

종료 코드 $?는 2이고 메시지는 다음과 같습니다.an unary op was expected.

답변1

그것은해야한다

some_func() {
  echo "$(( 3 + 5 ))"
}
[ "$(some_func)" -lt 10 ]

실패한 이유

$(some_func)으로 확장됩니다.산출그러나 아무것도 출력하지 않는 함수*(후행 개행 제외). 따라서 테스트는

[ -lt 10 ]

가장 기본적인 형태로는,테스트 [에서는 1~3개의 매개변수를 허용합니다.. 위에는 2개의 매개변수가 있으므로 Bash는 첫 번째 매개변수가 단항 연산자일 것으로 예상합니다. -lt바이너리이므로 오류 메시지가 나타납니다.

당신이 있었다적절하게 확장을 인용했습니다.~와 함께

[ "$(some_func)" -lt 10 ]

테스트에 빈 문자열이 있으므로 오류는 "정수 표현식 예상"입니다.

[ "" -lt 10 ]

그리고 아래가 아닌 이상사소하지 않은 상황, && true중복됩니다.

*확장은 인용되지 않았기 때문에 출력도 진행됩니다.단어 분리그리고파일 이름 확장. $IFS기본값에서 변경되지 않은 한 이는 현재 예에서 역할을 하지 않아야 합니다 .

답변2

$(cmd)얻는다표준 출력¹ 의 cmd결과로 확장하려면 다음을 수행해야 합니다 cmd.산출그것:

some_func() {
  echo "$(( 3 + 5 ))"
}
[ "$(some_func)" -lt 10 ]

다른 사람들이 이미 말했듯이. 그러나 이는 some_func하위 쉘 환경에서 실행되므로 변수 또는 기타 사항에 대한 수정 사항은 이후에 손실됩니다.

예를 들어, 다음을 수행하는 것은 의미가 없습니다.

counter=0
incr() { echo "$((++counter))"; }
while [ "$(incr)" -le 10 ]...

as는 $(incr)항상 1로 확장됩니다( counter서브쉘에서만 증가됩니다).

함수가 수치 결과를 반환하는 경우산술 평가, 다음을 지원하는 쉘이 필요합니다.수학 함수또는 .ksh93​ 하지 않습니다.zshbash

안에 zsh:

counter=0
incr() (( ++counter ))
functions -M incr

while (( incr() <= 10 )); do
  print $counter
done

안에 ksh93:

function .sh.math.incr i {
  # ksh93 functions must take at least one argument
  (( .sh.value = (counter += i) ))
}
while (( incr(1) <= 10 )); do
  print "$counter"
done

ksh93 또는 최신 버전의 mksh의 또 다른 대안은 하위 쉘을 도입하지 않는 명령 대체 형식을 사용하는 것입니다.

counter=0
function incr { print "$(( ++counter ))"; }
while [ "${ incr; }" -le 10 ]; do
  print "$counter"
done

또는 mksh:

counter=0
incr() (( REPLY = ++counter ))
while [ "${| incr; }" -le 10 ]; do
  print "$counter"
done

을 포함한 모든 POSIX 셸에서는 bash항상 미리 정의된 변수( $REPLY일반적으로 사용되는 변수)의 값을 반환할 수 있습니다.

counter=0
incr() { REPLY=$(( counter += 1 )); }
while incr; [ "$REPLY" -le 10 ]; do
  echo "$counter"
done

자세한 내용은 다음에서 확인할 수 있습니다.mksh의 valsub 기능에 대한 다른 Q&A에 대한 답변입니다.


¹ 후행 개행 문자가 제거되고 NUL 문자의 경우 bash따옴표를 잊어버렸기 때문에 여기서는 분할+글로브에 따라 달라질 수 있습니다.

답변3

명령 대체출력을 캡처합니다.명령이나 기능의. 해당 함수에는 출력이 없습니다.

변수 $?반환 코드기능의.

다음 중 하나를 수행하십시오.

some_func
(( $? < 10 )) && echo yes

또는 기능을 다음으로 변경하십시오.

some_func() {
    echo $(( 3 + 5 ))
}

[[ $(some_func) -lt 10 ]] && echo yes

[[...]]대신에 내가 어떻게 사용하고 있는지 확인하세요 [...]. 조건부 이중 괄호는 빈 값에 대해 더 관대합니다.

관련 정보