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

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

다음 표현식을 시도하면 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)다음으로 확장산출function* (후행 개행 빼기), 그러나 아무것도 출력하지 않습니다. 따라서 테스트는

[ -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 ]...

항상 $(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에 대한 답변은 다음과 같습니다.


¹ 후행 개행 문자를 제거하고 bashNUL 문자의 경우 따옴표를 잊어버렸기 때문에 여기에서 분할+glob이 적용됩니다.

답변3

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

$?변수는반환 코드함수.

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

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

또는 기능을 다음과 같이 변경하십시오.

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

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

[[...]]대신에 내가 어떻게 사용하는지 주목하세요 [...]. 이중 괄호 조건은 Null 값에 더 관대합니다.

관련 정보