zsh에서 함수에 조건문을 매개변수로 전달하는 방법은 무엇입니까?

zsh에서 함수에 조건문을 매개변수로 전달하는 방법은 무엇입니까?

나는 다음과 유사한 함수를 별칭으로 정의했습니다.

testif() {
    ([ $1 ]) && echo "true" || echo "false"
}

testit "1 == 2"..그러면 전화를 걸 수 있어요세게 때리다쉘과 출력은 false예상대로입니다. 하지만 작동하지 않습니다다루기 힘든. zsh에서 동일한 호출의 출력은 true.

  1. zsh에 이러한 함수를 작성할 수 있습니까?
  2. zsh가 오류를 출력하는 이유는 무엇입니까? zsh bash가 호환되어서는 안되나요?

답변1

매우 간단한 예일 뿐 아니라 여러분이 수행한 작업은 bash에서도 작동하지 않습니다.

$ testif 'hello world = hello world'
bash: [: too many arguments
false
$ testif '"hello world" = "hello world"'
bash: [: too many arguments
false
$ testif '* = *'
(usually false with an error message, but it depends on the files in the current directory)

$1다른 sh 유사 쉘과 달리 zsh에서는 실제로 "첫 번째 인수의 값 가져오기"를 의미하기 때문에 간단한 예제도 zsh에서는 작동하지 않습니다 (거의 확장 결과 null 단어가 발생하면 완전히 삭제합니다). bash 및 기타 sh와 유사한 쉘에서는 $1"첫 번째 인수의 값을 가져와 이를 단어로 분할하고 각 단어를 전역 패턴으로 처리"하는 것을 의미하는데 이는 거의 원하는 것이 아닙니다.


test다음과 같이 /single-brackets 명령 구문으로 조건을 전달할 수 있습니다.분리논쟁.

testif () {
  if [ "$@" ]; then echo true; else echo false; fi
}

이는 가능합니다( no 및 연산자 [와 같은 명령에 대한 제한이 있음).&&||

$ testif '*' = '*'
true
$ testif hello = hello
true
$ testif 'hello world' = 'hello world'
true
$ testif 0 = 00
false
$ testif 0 -eq 00
true

그러나 [조건을 통과할 타당한 이유가 있는 경우는 거의 없습니다. 전체 명령을 전달하고 싶을 수도 있습니다. 이를 통해 다른 유형의 조건(예: grep …또는 ) 을 전달할 수 있을 뿐만 아니라 if systemctl is-active …간단한 명령 이상이 필요한 경우 도우미 함수를 정의할 수 있습니다.

testif () {
  if "$@"; then echo "true"; else echo "false"; fi
}
$ testif [ 'hello world' = 'hello world' ]
true
$ testif grep -q : /etc/passwd
true

또 다른 방법은 전체 명령을 단일 문자열로 전달하여 eval함수 내에서 사용하는 것입니다.

testif () {
  if eval "$1"; then echo true; else echo false; fi
}
$ testif '[ "hello world" = "hello world" ]'
true
$ testif '[ "hello world" = "h*" ]'
false
$ testif '[[ "hello world" = "h*" ]]'
false
$ testif '[[ "hello world" = h* ]]'
true

관련 정보