我想编写一个“永久”函数,可以运行多个命令,直到使用 Ctrl-C 手动将其终止。基本上,从 zsh 命令行,我知道我可以做到这一点,而且效果很好:
$ while {} { ls ; sleep 1 }
它将永远重复调用ls
和sleep 1
。
我无法找到将这样的内容转换为函数的语法。例如:
forever() { while {} { "${@}" } }
然后我想要用类似以下的方式调用它:
$ forever ( ls ; sleep 1 )
当while {} {<commands>}
和forever {<commands>}
几乎没有什么不同时,这可能看起来很愚蠢。但我真正想要的最终目标是“永远睡眠”功能,我可以在其中说类似
$ forever-sleep 5 ls -l
$ forever-sleep 5 ( ls -l a ; ls -l b )
并且它将$1
在执行我给出的命令几秒钟后永远处于休眠状态(直到我使用 Ctrl-C 手动将其杀死)。
(我尝试了很多组合和嵌套,,,,,,,,等()
,但我只是想不出如何让函数和命令行都不出现语法错误、解析错误等。)(())
{}
[]
[[]]
""
''
所以,
- 是否已经存在与此“永远”的想法类似的东西?
- 这在函数中可行吗?(我更喜欢可以放入函数中
.zshrc
而不是使用单独的可执行 shell 脚本。)
答案1
您几乎已经到达:
forever-sleep() {
if [[ ! $1 -gt 0 ]]; then
print "Usage $0 [time in sec] command -parameter"
return 2
fi
local time=$1
shift 1
while true; do
eval "$@"
print -- "### finished: $(date) ###############################################"
sleep $time
done
}
那么语法forever-sleep [time in sec] command -parameters
就是
$ forever-sleep 2 date +%s
1373873888
1373873890
1373873892
1373873894
...
几点说明:
$1 -gt 0
通过评估 来执行基本检查,以确定第一个参数是否为数字$1 > 0
。负等待时间似乎不合理。- 我用过
while true; do ... done
,但你的while {} {...}
语法也有效。 shift 1
用于丢弃函数的第一个参数(保存在中$time
,以便以后"$@"
可以方便地使用该变量。eval "$@"
相比之下,"$@"
它能够做一些更高级的事情,比如forever-sleep 2 'foo=$(date); echo $foo'
请注意后一个命令中的单引号!
- 打印调用提供了一个视觉分隔符——不管你喜欢与否
;)