Сценарій Bash для моніторингу зміни файлів та виконання команди


12

У мене папка з купою папок, ці папки asciidoctorсформували подані з .adocрозширенням.

Кожен раз, коли я вносив зміни до файлів (що часто), мені потрібно запустити

asciidoctor -q filename.adoc

скласти його у формат HTML.

Я намагаюся автоматизувати процес. до цих пір я прийшов із цим за допомогою entr :

ls *.adoc | entr asciidoctor -q *.adoc

але працює лише з існуючою папкою, а не для папок. Я спробував цю варіацію, але вона не працює:

find . -name '*.adoc' | entr asciidoctor -q *.adoc

Будь-які ідеї, як я міг реалізувати цей автоматизований процес для всіх підпапок?


1
Можливий дублікат того, як ви виявите зміни файлів
Anwar

Відповіді:


17

Linux надає приємний інтерфейс для моніторингу всіх подій файлової системи, таких як створення, модифікація та видалення файлів. Інтерфейс - це inotifyсімейство системних викликів, утиліти простору користувачів, які використовують ці виклики, надаються inotify-toolsпакетом в Ubuntu (доступний у всесвітньому сховищі). Якщо у вас його ще немає, встановіть:

sudo apt-get install inotify-tools

inotify-toolsзабезпечує inotifywaitі inotifywatchбінарні файли, нам потрібен перший.


Таким чином, ви хочете запустити команду, asciidoctor -q some_fileколи будь-який .adocфайл буде змінено ( some_fileзамінить його), якщо так, якщо ваші .adocфайли знаходяться в каталозі /foo/bar, ви можете встановити годинник:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
  • -qдозволяє беззвучний режим, без інформації від inotifywaitсебе

  • -m вмикає режим монітора, інакше він вийде після першої події

  • --event modify, нас цікавить лише modifyподія, тобто коли файл змінено. Інші можливі значення включають open, і closeт.д.

  • --format %w, ми хочемо лише змінити ім'я файлу, а не купу іншої інформації, оскільки ми будемо використовувати ім'я файлу як вхід до іншої команди

  • /foo/bar/*.adocбуде розширено на всі .adocфайли в /foo/barкаталозі


Тепер вищесказане покаже вам ім'я файлу, коли будь-яке змінено, тепер запустіть команду на ім'я файлу (якщо припустимо, що команда бере аргументи через STDIN):

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | asciidoctor -q

Ви також можете встановити рекурсивний годинник на каталог, після чого вам потрібно буде grepлише фільтрувати потрібні файли. Тут налаштування перегляду рекурсивно ( -r) на каталог /foo/barта використання grepдля фільтрації лише .adocфайлів:

inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | asciidoctor -q

Під час перегляду каталогів специфікатор формату виводу визначає %wім'я каталогу, тому нам потрібно %fотримати ім'я файлу. Під час перегляду файлів %fбуде вирішено порожній рядок.

Зауважте, що ви також можете запускатись inotifywaitу режимі daemon ( -d), ви також можете сценарій всього, та / або запускати у фоновому режимі та / або грати з ним більше інших параметрів.

Крім того, ви можете замінити asciidoctorбудь-яку іншу команду на ваш вибір, якщо хочете.

Поставте прапорець, man inotifywaitщоб отримати більше уявлень.


Спасибі це спрацювало. Я теж щось подібне для OSX. але я думаю, це не правильне місце для запитання.
висівки

@bran Так, IMHO перейдіть до UL , ви можете використовувати це в якості посилання.
heemayl

Чудова відповідь, лише незначна корекція. -q робить програму "менш багатослівною", -qq (подвійний q) робить її повністю безшумною, за винятком фатальних помилок.
jotadepicas

4

Використання inotifywait- це типовий підхід, але також існує окрема утиліта, яка називається, inotify-hookableщо дозволяє лише запустити команду, коли файл (або каталог) змінюється:

inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'

Це здається, що він виходить після запуску команди один раз; Я не бачу варіанту для безперервного перегляду, тому ви можете зробити щось на кшталт:

while true; do
    inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
    echo "== $(date) : executed, continuing to monitor..."
done

Зверніть увагу, є варіанти для моніторингу кількох файлів або каталогу, рекурсивно та варіантів ігнорування файлів / шляхів.


inotify-hookable не виходить після запуску команди для мене. Хм
Макс

inotify-hookable встановлюється з іншого пакету:sudo apt-get install inotify-hookable
Бруно Сільвано

3

Там є багато інструментів, особливо якщо ви шукаєте у своєму сховищі

apt-cache search monitor | grep file

що дає нам багато інструментів. Але не потрібно їх тестувати, бо я це зробив.

Я перевірив ці інструменти та багато інших:

  • прищеплювати
  • fswatch
  • перегляд файлів
  • зразок
  • файли змінені
  • вступ

Серед цих інструментів я знайшов три з них корисних і надійних:

  • прямий | GNU написано на С
  • iwatch | в Перлі
  • гнід

І між цими трьома напрямками найкращий без сумнівів.

Це настільки корисно і надійно використовувати, що я використовував його для простого трубопроводу зі своїми мікросервісами, які у мене є.

direvent.conf файл для перегляду

syslog {
    facility local0;
    tag "direvent";
    print-priority yes;
}

watcher {
    path /var/www/html/ir/jsfun/build/react recursive;
    file "*.js";
    event write;
    command "/usr/bin/xdotool search --onlyvisible  --class firefox key F5";
    option (stdout, stderr, wait);
}

Це лише один із конфігураційних файлів, у яких, коли є зміна для запису , виконується ця команда - яка може бути і сценарієм .

Не потрібно використовувати whileцикл або інші речі.


особливості

  • рекурсивно переглядаючи каталог
  • може бути запущено на передньому плані або на тлі як демон
  • портативний. У мене це є в Ubuntu, а також на сервері CentOS7
  • звіт про ім'я файлу
  • регулярний вираз для підтримки відповідності файлів
  • перегляд mulit-файлів (дивіться більше лише одного типу файлів)
  • синхронізувати виконання команд (якщо у нас є мультиварка)
  • обробка syslog (увійдіть у syslog, якщо ми хочемо)
  • простий та хороший дизайн CLI та конфігураційного файлу для роботи

Розроблено Сергієм Позняковим .


Встановлення

sudo apt install direvent

Але встановити його за допомогою його вихідного коду досить просто та просто, що дає останню версію (зараз це: 5.1).


-3

Ну і рекомендую наступне.

#!/bin/bash
#Script
for SRC in *.adoc; 
      do
      asciidoctor -q $SRC
  done

1
OP хоче запустити команду лише тоді, коли будуть внесені зміни ..
heemayl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.