나는 다음과 유사한 함수를 별칭으로 정의했습니다.
testif() {
([ $1 ]) && echo "true" || echo "false"
}
testit "1 == 2"
..그러면 전화를 걸 수 있어요세게 때리다쉘과 출력은 false
예상대로입니다. 하지만 작동하지 않습니다다루기 힘든. zsh에서 동일한 호출의 출력은 true
.
- zsh에 이러한 함수를 작성할 수 있습니까?
- 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