1

Я хочу написать "навсегда" функцию, чтобы я мог запускать несколько команд, пока я не убью ее вручную с помощью 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 а не иметь отдельный исполняемый скрипт оболочки.)

1 ответ1

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'
    

    Обратите внимание на одинарные кавычки в последней команде!

  • Вызов печати дает визуальный разделитель - нравится вам это или нет ;)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .