Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to write a "forever" function that I can run multiple commands until I manually kill it with Ctrl-C. Basically, from the zsh command line, I know I can do this, and this works fine:

$ while {} { ls ; sleep 1 }

which will repeated call ls and sleep 1, forever.

I can't figure out a syntax to turn something like that into a function. Something like:

forever() { while {} { "${@}" } }

which I want to then then call with something like:

$ forever ( ls ; sleep 1 )

It probably seems silly when while {} {<commands>} and forever {<commands>} is hardly very different. But what I really want as my end goal is a "forever-sleep" function, where I can say something like

$ forever-sleep 5 ls -l
$ forever-sleep 5 ( ls -l a ; ls -l b )

and it will sleep $1 seconds after executing the command(s) I give it, forever (until I manually kill it with Ctrl-C).

(I've tried lots of combinations and nestings of (),(()),{},[],[[]],"",'', and such, and I just can't figure out how to get both the function and the command line not to have syntax errors, parse errrors, etc.)


  • Is there something similar to this "forever" idea already?
  • Is this possible in a function? (I would prefer a function I can put in my .zshrc rather than having a separate executable shell script.)
share|improve this question
up vote 1 down vote accepted

You were almost there:

forever-sleep() {
   if [[ ! $1 -gt 0 ]]; then
     print "Usage $0 [time in sec] command -parameter"
     return 2
   local time=$1
   shift 1
   while true; do
      eval "$@"
      print -- "### finished: $(date) ###############################################"
      sleep $time

The syntax then is forever-sleep [time in sec] command -parameters, like

$ forever-sleep 2 date +%s

A few remarks:

  • $1 -gt 0 implements a rudimentary check, if the first parameter is numerically by evaluating $1 > 0. A negative waiting time seems not sensible.
  • I used while true; do ... done, but your while {} {...} syntax works, too.
  • shift 1 is used to discard the first argument to the function (which is saved in $time, so that later the "$@" variable can be used for convenience.
  • eval "$@" in contrast to a mere "$@" makes it possible to do some more advanced stuff like

    forever-sleep 2 'foo=$(date); echo $foo'

    Please notice the single quotes in the latter command!

  • The print invocation gives a visual separator -- like it or not ;)
share|improve this answer
Beautiful. Thank you. The eval is what I was missing. (I knew about shift, but thanks for the completeness.) – snapshoe Jul 15 '13 at 15:13

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.