매개변수 대체의 기본값을 요소 배열로 설정하는 방법은 무엇입니까?

매개변수 대체의 기본값을 요소 배열로 설정하는 방법은 무엇입니까?

나는 zsh를 사용하고 있으며 다음 기능이 있습니다.

function timer-raw() {
    # Just think `loop fsayd` is `echo hi` for the purposes of this question.
    eval "sleep $((($1)*60))" && eval ${(q+@)@[2,-1]:-loop fsayd}
}

timer-raw의 첫 번째 매개변수는 대기할 시간(분)을 알려줍니다. 나머지 매개변수(있는 경우)는 eval명령줄에 입력한 것처럼 대기 후에 편집됩니다.

timer 3 echo sth
# After 3 minutes, echoes `sth`.

그러나 더 이상 인수가 제공되지 않으면 기본 명령을 실행하고 싶습니다 loop fsayd.

timer 4
# runs `loop fsayd` after 4 minutes

문제는 두 단어로 바꾸고 싶지만 loop fsayd방법을 모른다는 것입니다. 또한 이러한 변형을 시도했지만 작동하지 않습니다.

"${(q+@)${@[2,-1]:-loop fsayd}}"
"${(q@)${(q@)=@[2,-1]:-loop fsayd}}"
"${(qq@)=@[2,-1]:-loop fsayd}"

"작동하지 않는다"는 것은 간단한 작업이 실패하거나 올바른 수의 입력 인수를 반환하지 못한다는 것을 timer 0의미 합니다 command not found. timer 0 ff hi 'man hi jk k'( ff() echo "$#")

참고: 를 사용하고 싶지 않습니다 test -z "${@[2,-1]}".

답변1

하하, 알아냈어요:

function timer-raw() {
    eval "sleep $((($1)*60))" && eval ${(q+@)@[2,-1]:-${(z)/#/loop fsayd}}
}

${name/pattern/repl}이는 빈 문자열인 ""(nothing)이라는 존재하지 않는 변수의 내용을 대체( )합니다. #단어 분할(옵션)을 수행하는 동안 (빈) 문자열(패턴)의 시작 부분을 루프 fsayd로 대체합니다 (z). .... :D

답변2

변수에 기본값을 정의할 수 있으면 다음을 수행할 수 있어야 합니다.

function timer-raw() {
    defs=( loop fsayd )
    eval "sleep $((($1)*60))" && eval ${(q+@)@[2,-1]:-$defs}
}

개인적으로 나는 eval을 사용하지 않지만 다음을 수행합니다.

function timer-raw() {
    defs=( loop fsayd )
    sleep ${1}m && ${@[2,-1]:-$defs}
}

관련 정보