Выполнить команду при изменении файла в Linux

Категория: Utilities

Отслеживаем изменения файла и запускаем команду.

Entr

Run arbitrary commands when files change. http://eradman.com/entrproject/ | https://github.com/eradman/entr/

@see https://www.cloudsavvyit.com/5736/how-to-run-a-linux-command-when-a-file-set-changes/

Установка entr:

sudo pacman -Si entr
sudo pacman -S entr
О пакете...
Пакет весит всего 30 kb и не имеет зависимостей
Пакеты (1) entr-5.0-1
Будет загружено:    0,01 MiB
Будет установлено:  0,03 MiB

Идеально :)

$ pacman -Si entr
Репозиторий          : community
Название             : entr
Версия               : 5.0-1
Описание             : Run arbitrary commands when files change
Архитектура          : x86_64
URL                  : http://eradman.com/entrproject
Лицензии             : MIT
Группы               : Нет
Предоставляет        : Нет
Зависит от           : Нет
Доп. зависимости     : Нет
Конфликтует с        : Нет
Заменяет             : Нет
Размер загрузки      : 13,69 KiB
Установленный размер : 27,43 KiB
Сборщик              : Filipe Laíns <lains@archlinux.org>
Дата сборки          : Вс 11 июл 2021 01:02:42
Проверен             : MD5  SHA-256  Подпись

Пример отслеживания изменений:

touch watch.txt
ls watch.txt | entr wc /_
ls | entr echo "$(date +'%F %T')" /_       ## дата  файл
ls /var/log/some.log | entr tail -n 50 /_  ## не ловит изменение лога в alpine, если лог пишется через rsyslog!

* Параметр /_ это placeholder имени файла, который был передан в entr. Если в entr передается группа файлов, например *.txt, параметр /_ будет заменен последним измененным файлом.

Перезагрузка Nginx при изменении конфига:

ls /etc/nginx/sites-available/*.conf | entr -p -s 'sudo nginx -t && sudo service nginx reload'
ls /etc/nginx/sites-available/*.conf | entr -p -s 'sudo nginx -t && sudo systemctl reload nginx'
Опции entr
-p  Postpone.  Отложить первое выполнение утилиты до тех пор, пока файл не будет изменен
-r  Reload.    Reload a persistent child process. НЕ прерывайте по Ctrl+C! Нажмите Q.
    [запустить процесс] » [блокировать до изменения любого из перечисленных файлов] » [завершить фоновый процесс] » [ждем завершения процесса]
-d  Directory. Отслеживать добавление новых файлов в директории
-c  Clean.     Очищать экран перед запуском команды
Man
NAME
     entr — run arbitrary commands when files change

SYNOPSIS
     entr [-acdnprsz] utility [argument /_ ...]

DESCRIPTION
     A list of files provided on standard input, and the utility is executed using the supplied arguments if any of them change.  entr waits for the child process to finish before responding to subsequent file system events.  A
     TTY is also opened before entering the watch loop in order to support interactive utilities.

     The arguments are as follows:

     -a      Respond to all events which occur while the utility is running.  Without this option, entr consolidates events in order to avoid looping.  This option has no effect in conjunction with the -r flag.

     -c      Clear the screen before invoking the utility specified on the command line.  Specify twice to erase the scrollback buffer.

     -d      Track the directories of regular files provided as input and exit if a new file is added.  This option also enables directories to be specified explicitly.  Files with names beginning with ‘.’ are ignored.
             Отслеживайте каталоги обычных файлов, предоставленных в качестве входных данных, и выходите, если добавляется новый файл. Эта опция также позволяет явно указывать каталоги. Файлы с именами, начинающимися с «.», игнорируются.

     -n      Run in non-interactive mode.  In this mode entr does not attempt to read from the TTY or change its properties.

     -p      Postpone the first execution of the utility until a file is modified.

     -r      Reload a persistent child process.  As with the standard mode of operation, a utility which terminates is not executed again until a file system or keyboard event is processed.  SIGTERM is used to terminate the
             utility before it is restarted.  A process group is created to prevent shell scripts from masking signals.  entr waits for the utility to exit to ensure that resources such as sockets have been closed.  Control of the
             TTY is not transferred to the child process.

     -s      Evaluate the first argument using the interpreter specified by the SHELL environment variable.  If standard output is a TTY, the name of the shell and exit code is printed after each invocation.

     -z      Exit after the utility completes.  When combined with -r the utility will be restarted again only in response to commands or file system events.

     The first argument named /_ is replaced with the absolute path of the first file to trigger an event.  The first file under watch is used as the default.  If the -s option is used, the name of the first file to trigger an
     event can be read from $0.

COMMANDS
     entr listens for keyboard input and responds to the following commands:

     ⟨space⟩  Execute the utility immediately.  If the -r option is set this will terminate and restart the child process as if a file change event had occurred.

     q        Quit; equivalent pressing ⟨control-C⟩.

ENVIRONMENT
     PAGER         Set to /bin/cat by default to prevent interactive utilities from waiting for keyboard input if output does not fit on the screen.

     SHELL         Specify the shell to use with the -s flag.  The default is /bin/sh.

     EV_TRACE      Print file system event messages.

EXIT STATUS
     If the -z flag is set and the utility is successfully executed, the status of the child process is returned.  Otherwise entr normally returns one of the following values:

           0       Normal termination after receiving SIGINT
           1       No regular files were provided as input or an error occurred
           2       A file was added to a directory and the directory watch option was specified

EXAMPLES
     Rebuild a project if source files change, limiting output to the first 20 lines:

           $ find src/ | entr -s 'make | sed 20q'

     Launch and auto-reload a node.js server:

           $ ls *.js | entr -r node app.js

     Clear the screen and run a query after the SQL script is updated:

           $ echo my.sql | entr -cp psql -f /_

     Rebuild project if a source file is modified or added to the src/ directory:

           $ while sleep 0.1; do ls src/*.rb | entr -d make; done

     Auto-reload a web server, or terminate if the server exits

           $ ls * | entr -rz ./httpd
Внимание!

Не работает с файлами устройств.

> Unfortunately inotify(7) only supports "regular" files not devices and files used as an API. It's a limitation in the kernel.

Видимо, поэтому и не отслеживает rsyslog логи.

Нашел еще такие варианты:

  • inotify-tools 3.22.1 - is a C library and a set of command-line programs for Linux providing a simple interface to inotify.
    Это больше для сбора статистики. Предоставляет утилиты:
    - inotifywait - просто блокирует события inotify, что делает ее пригодной для использования в сценариях оболочки.
    - inotifywatch - собирает и выводит статистику использования файлов/каталогов.
    https://github.com/inotify-tools/inotify-tools/
  • fswatch 1.16.0 - fswatch is a frontend of libfswatch, a library with C and C++ binding.
    Пакет в AUR репе. Документация не очень. Забил..
  • watchdog 2.1.6 - Python API and shell utilities to monitor file system events. https://pypi.org/project/watchdog/
    Слишком жирный для задачи просто отслеживать файл.
pacman -Si inotify-tools

#entr #watch #notify #file changes #filesystem #fs #watch file #отслеживание изменений файлов

категория: Utilities