如何将参数替换中的默认值设置为元素数组?

如何将参数替换中的默认值设置为元素数组?

我正在使用 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 foundtimer 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}) 名为“”(无任何内容)的不存在变量的内容——这是一个空字符串——#用循环 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}
}

相关内容