如何将多个命令作为函数的参数来调用?

如何将多个命令作为函数的参数来调用?

我想编写一个“永久”函数,可以运行多个命令,直到使用 Ctrl-C 手动将其终止。基本上,从 zsh 命令行,我知道我可以做到这一点,而且效果很好:

$ while {} { ls ; sleep 1 }

它将永远重复调用lssleep 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'
    

    请注意后一个命令中的单引号!

  • 打印调用提供了一个视觉分隔符——不管你喜欢与否;)

相关内容