Bash script untuk memonitor perubahan file dan menjalankan perintah

12

Saya memiliki folder dengan banyak subfolder, folder ini telah asciidoctordiformat dengan .adocekstensi.

Setiap kali saya membuat perubahan pada file (yang sering) saya harus menjalankan

asciidoctor -q filename.adoc

untuk mengkompilasinya ke dalam format HTML.

Saya mencoba mengotomatiskan prosesnya. sejauh ini saya telah datang dengan menggunakan entr ini :

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

tetapi hanya berfungsi dengan folder yang ada bukan untuk subfolder. Saya sudah mencoba variasi ini, tetapi tidak berhasil:

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

Adakah ide bagaimana saya bisa menerapkan proses otomatis ini untuk semua subfolder?

dedak
sumber
1
Kemungkinan duplikat dari Bagaimana Anda mendeteksi perubahan file
Anwar

Jawaban:

17

Linux menyediakan antarmuka yang bagus untuk memantau semua peristiwa sistem file seperti membuat, memodifikasi, menghapus file. Antarmuka adalah inotifykumpulan dari panggilan sistem, utilitas userspace yang memanfaatkan panggilan ini disediakan oleh inotify-toolspaket di Ubuntu (tersedia di repositori semesta). Jika Anda belum memilikinya, instal dengan:

sudo apt-get install inotify-tools

inotify-toolsmenyediakan inotifywaitdan inotifywatchbinari, kita perlu yang pertama.


Jadi Anda ingin menjalankan perintah asciidoctor -q some_fileketika .adocfile apa pun dimodifikasi ( some_fileakan diganti dengan itu), jika demikian dengan asumsi .adocfile Anda ada di direktori /foo/bar, Anda dapat mengatur arloji:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
  • -qmengaktifkan mode senyap, tidak ada info dari inotifywaitdirinya sendiri

  • -m mengaktifkan mode monitor, jika tidak maka akan keluar setelah acara pertama

  • --event modify, Kami hanya tertarik pada modifyacara yaitu ketika file diubah Nilai-nilai lain yang mungkin termasuk open, closedll.

  • --format %w, kami hanya ingin nama file yang diubah daripada banyak info lain karena kami akan menggunakan nama file sebagai input ke perintah lain

  • /foo/bar/*.adocakan diperluas ke semua .adocfile di bawah /foo/bardirektori


Sekarang yang di atas akan menunjukkan kepada Anda nama file setiap kali ada modifikasi, sekarang untuk menjalankan perintah pada nama file (dengan asumsi perintah mengambil argumen melalui STDIN):

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

Anda juga dapat mengatur arloji rekursif pada direktori, yang kemudian perlu Anda gunakan grepuntuk memfilter file yang diinginkan saja. Di sini, setel arloji secara rekursif ( -r) pada direktori /foo/bardan gunakan grepuntuk memfilter hanya .adocfile:

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

Saat menonton direktori, specifier format output %wmenyelesaikan ke nama direktori, jadi kita perlu %fmendapatkan nama file. Saat menonton file, %fakan menyelesaikan string kosong.

Perhatikan bahwa, Anda juga dapat menjalankan inotifywaitdalam -dmode daemon ( ), Anda juga dapat skrip semuanya, dan / atau berjalan di latar belakang, dan / atau bermain dengannya lebih banyak pilihan lain.

Juga, Anda dapat mengganti asciidoctordengan perintah lain pilihan Anda, jika Anda mau.

Periksa man inotifywaituntuk mendapatkan lebih banyak ide.

heemayl
sumber
Terima kasih itu berhasil. Saya juga sesuatu yang mirip untuk OSX. tapi kurasa ini bukan tempat yang tepat untuk bertanya.
dedak
@ Bar Ya, IMHO pergi ke UL , Anda dapat menggunakan ini sebagai referensi.
heemayl
Jawaban bagus, hanya koreksi kecil. -q membuat program "less verbose", -qq (q ganda) membuatnya benar-benar diam kecuali untuk kesalahan fatal.
jotadepicas
4

Menggunakan inotifywaitadalah pendekatan khas, tetapi ada juga utilitas terpisah yang disebut inotify-hookableyang hanya memungkinkan Anda menjalankan perintah ketika file (atau direktori) berubah:

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

Tampaknya keluar setelah memicu perintah sekali; Saya tidak melihat opsi untuk menonton terus-menerus, sehingga Anda dapat melakukan sesuatu seperti:

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

Perhatikan ada opsi untuk memantau beberapa file atau direktori, secara rekursif, dan opsi untuk mengabaikan file / jalur.

michael
sumber
inotify-hookable tidak keluar setelah menjalankan perintah untuk saya. Hmm
Maks
inotify-hookable diinstal dari paket yang berbeda:sudo apt-get install inotify-hookable
Bruno Silvano
3

Ada banyak alat di luar sana, khususnya jika Anda mencari melalui repositori Anda

apt-cache search monitor | grep file

yang memberi kita banyak alat. Tetapi Anda tidak perlu menguji mereka karena saya melakukan itu.

Saya telah menguji alat ini dan banyak lainnya:

  • batalkan
  • fswatch
  • filewatch
  • carikan
  • file berubah
  • entr

Di antara alat-alat ini saya menemukan tiga di antaranya berguna dan dapat diandalkan:

  • mengerikan | GNU ditulis dalam C
  • iwatch | dalam Perl
  • fsniper

Dan di antara ketiganya, yang mengerikan adalah yang terbaik tanpa keraguan.

Sangat berguna dan dapat diandalkan untuk digunakan sehingga saya telah menggunakannya untuk pipa sederhana dengan layanan microser yang saya miliki.

direvent.conf file untuk menonton

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);
}

Ini hanya salah satu file konfigurasi yang saya miliki di mana setiap kali ada perubahan untuk menulis maka perintah ini dijalankan - yang bisa menjadi skrip juga.

Tidak perlu menggunakan whilelingkaran atau hal lain.


fitur

  • secara rekursif menonton direktori
  • dapat dijalankan di foreground atau background sebagai daemon
  • portabel. Saya memilikinya di Ubuntu dan juga server CentOS7
  • laporan nama file
  • regex untuk mendukung pencocokan file
  • menonton file mulit (tonton lebih dari satu jenis file)
  • sinkronisasi eksekusi perintah (jika kita memiliki multi-watcher)
  • penanganan syslog (login ke syslog jika kita mau)
  • CLI dan config file desain mudah dan baik untuk bekerja dengannya

Dikembangkan oleh Sergey Poznyakoff .


Menginstal

sudo apt install direvent

Tetapi menginstalnya menggunakan kode sumbernya cukup mudah dan langsung yang memberi Anda versi terakhir (sekarang adalah: 5.1).

Shakiba Moshiri
sumber
-3

Yah saya sarankan yang berikut ini.

#!/bin/bash
#Script
for SRC in *.adoc; 
      do
      asciidoctor -q $SRC
  done
SAGAR Nair
sumber
1
OP ingin menjalankan perintah hanya ketika modifikasi dilakukan ..
heemayl