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