Для практики использования каналов и контекста мы напишем утилиту, которая будет работать схожим образом как и встроенная Linux утилита watch
. Эта утилита запускает некоторую указанную команду с заданным интервалом времени и выводит её результат на экран.
Она может быть полезна, если вы ждете какого-то конкретного результата и чтобы не повторять ввод команды вручную вы можете использовать watch
.
Напимер вы хотите узнать когда изменится статус какого-то сервиса и не хотите каждый раз вводить systemctl status <service_name>
, вы можете просто запустить watch systemctl status <service_name>
.
Для того чтобы понять как она работает запустите watch date
и посмотрите как каждые 2 секунды выводится текущее время в консоль.
Конфигурация уже реализована. Она позволяет выбрать команду и интервал между запусками в следующем виде watch -interval duration command args
, например watch -interval 1s ls -1 .
.
Модифицировать программу так, чтобыЖ
- она выполняла команду по таймеру
- могла реагировать на сигналы
SIGINT
иSIGTERM
и завершать работу после того как текущий запуск команды завершится. Но перед завершением команда должна писать в консоль\nexiting...
При получении сигнала мы должны отменять контекст, который передается в функциюrepeat
Для реакции отмену контекста можно использовать либо цикл, либоselect
- Обратите особое внимание на получение всех нераспаршенных аргументов через flag.Args()
- Обратите внимание на то как можно запустить дочерний процесс через
exec.Command()
иexec.Cmd.Output()
- Сигналы (например SIGINT) можно отправить процессу через
kill -s SIGINT <pid>
, где<pid>
- это идентификатор процесса, который можно узнать черезpgrep watch
. Также это можно сделать из консоли: в Linux это Ctrl+C, в MacOS это Ctrl+.
- Запустите программу через
make run
- она должна раз в секунду выдавать текущее время. - Запустите команду
make kill
- она должна завершить работу программыwatch
. - В консоли в которой была запущена программа должно появиться сообщение
exiting...
и программа должна завершиться.
- сигналы - подпишитесь на сигналы
SIGINT
иSIGTERM
. При получении сигнала отмените контекст (в отдельной горутине вызовитеcancel()
) - time.Ticker - используйте для повторения команды с заданным интервалом. После создания тикера используйте канал
ticker.C
для получения событий запуска команды