Я бы сказал, что механизм для этого в сценарии оболочки является вполне адекватным решением, и что механизм для этого на основе операционной системы (чтобы мне не приходилось вручную запускать фоновую программу) просто означает помещение этого решения в процесс. менеджер, такой как s6, runit, системный модуль или даже запись inittab, если вы работаете в системе sysvinit.
Независимо от механизма поддержания его работы, мне нравится entr для просмотра файлов. Простой, по сути, составной (например, тривиально, чтобы положить в диспетчере процессов).
Вот скрипт для просмотра /path/to/file
и запуска /usr/local/bin/do_stuff
при его изменении:
#!/bin/bash
exec entr /usr/local/bin/do_stuff < <(echo /path/to/file)
Это все, что нужно сделать. Поместите это в файл run
runit или s6, поместите его в строку ExecStart
модуля systemd или вызовите этот скрипт из строки в inittab
. Хотя, если вы поместите его в inittab
вы, вероятно, захотите добавить где-нибудь sleep
, так как sysvinit не ограничивает скорость процессов, которые сразу же завершаются неудачей из-за ошибок в написании, отсутствующих файлов или чего-то подобного.
Почему бы просто не echo /path/to/file | entr /usr/local/bin/do_stuff
? При работе под управлением процесса важно, чтобы управляемый процесс находился непосредственно под супервизором, чтобы он работал правильно, например, при завершении работы. Если оболочка работает под супервизором, она будет перехватывать любые сигналы TERM
, INT
или KILL
а не процесс, который она выполняет, и не будет их передавать. Или он выйдет и оставит процесс осиротевшим. exec
удаляет оболочку из цепочки процессов. (exec
на правой стороне |
не имеет значения)
Или просто используйте оболочку, которая никогда не окажется посредине, execline:
#!/bin/execlineb
pipeline -d {
echo /path/to/file
} entr /usr/local/bin/do_stuff