Cara menggunakan inotifywait untuk menonton direktori pembuatan file dari ekstensi tertentu

21

Saya telah melihat jawaban ini .

Anda harus mempertimbangkan menggunakan inotifywait, sebagai contoh:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

Pertanyaan saya adalah, skrip di atas mengawasi direktori untuk pembuatan file jenis apa pun, tetapi bagaimana cara memodifikasi inotifywaitperintah untuk melaporkan hanya ketika file dengan jenis / ekstensi tertentu dibuat (atau dipindahkan ke direktori) - mis. Seharusnya melaporkan ketika ada .xmlfile yang dibuat.

APA YANG SAYA MENCOBA:

Saya telah menjalankan inotifywait --helpperintah, dan telah membaca opsi baris perintah. Ini memiliki --exclude <pattern>dan --excludei <pattern>perintah untuk MENGECUALIKAN file dari jenis tertentu (dengan menggunakan regEx), tapi saya perlu cara untuk MENGMASUK hanya file dari jenis / ekstensi tertentu.

Pemalu
sumber
BTW, menggunakan di pathatas mungkin bukan nama variabel terbaik jika Anda ingin bermain dengan ini terlebih dahulu dalam shell. Jika Anda menggunakannya, maka Anda tidak akan dapat menggunakan perintah dan semuanya karena ini pada dasarnya hanya menimpa standar PATH. Karenanya saya merekomendasikan menggunakan nama var alternatif, seperti fpathsebagai gantinya. yaitu while read fpath action filemaka setiap perintah standar yang biasanya tersedia dari shell Anda akan tetap ada.
Baptiste Mathus
agak konyol karena tidak ada opsi sertakan.
erandros

Jawaban:

17

bagaimana cara memodifikasi perintah inotifywait untuk melaporkan hanya ketika file jenis / ekstensi tertentu dibuat

Harap perhatikan bahwa ini adalah kode yang belum diuji karena saya tidak memiliki akses ke inotifysekarang. Tetapi sesuatu yang mirip dengan ini seharusnya bekerja:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
            echo "xml file" # If so, do your thing here!
        fi
    done
undang-undang
sumber
2
Ini berhasil dan saya telah mengujinya dengan inotifywait.
TheBetterJORT
1
Bagaimana Anda menjalankan ini? Apakah itu perintah satu kali, atau apakah itu perlu dijalankan dalam satu lingkaran atau semacamnya? Mungkin sebagai bagian dari incron(saya harap tidak).
SDsolar
@ SDolar Ini bervariasi. Bagi saya, saya biasanya menjalankan inotifydengan nohupatau memulainya dengan layanan systemd kustom. Paling sering yang terakhir.
maulinglawns
9

Gunakan negatif ganda:

inotifywait -m --exclude "[^j][^s]$" /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
    done

Ini hanya akan mencakup file javascript

Jonas Earendel
sumber
1
Bagus, saya suka itu menggeser pemfilteran inotifywaitdaripada membuatnya menghasilkan output besar untuk semua file dan menyaring setelah itu (seperti pada jawaban lainnya). Belum mencoba, tapi saya kira itu akan melakukan sedikit lebih cepat.
TMG
Inilah yang saya cari. Cara memodifikasi --excludeinput untuk menonton .extfile. Ini dijalankan hanya sekali atau dalam untuk loop?
kurokirasama
Ini adalah dasmon, jadi itu akan berjalan sampai crash atau Anda mematikannya :)
Jonas Earendel
Maaf, melewatkan pertanyaan pertama. inotifywait -m --exclude "[^.][^e][^x][^t]$" /home/jonas/Skrivbord/test -e create -e moved_to | while read path action file; do echo "The file '$file' appeared in directory '$path' via '$action'" done Saya yakin regex dapat dioptimalkan, tetapi bayi ini bekerja :)
Jonas Earendel
Terima kasih !! Saya akan mencobanya!!
kurokirasama
3

Sementara pendekatan ganda-negatif dari jawaban sebelumnya adalah ide yang bagus karena (seperti yang dicatat TMG) ​​memang mengubah pekerjaan penyaringan inotifywait, itu tidak benar.

Misalnya, jika file berakhir as maka tidak akan cocok [^j][^s]$karena huruf terakhir stidak cocok [^s], oleh karena itu tidak akan dikecualikan.

Dalam istilah Boolean, jika Sadalah pernyataan:

"Surat terakhir adalah s "

dan J merupakan pernyataan:

"Surat kedua dari belakang adalah j "

maka nilai --excludeparameter semantik harus sama dengan not(J and S), yang oleh hukum De Morgan adalah not(J) or not(S).

Masalah potensial lain adalah bahwa dalam zsh, $pathadalah variabel bawaan yang mewakili setara dengan array$PATH , sehingga while read path ...baris tersebut akan benar-benar kacau $PATHdan menyebabkan semuanya menjadi tidak dapat dieksekusi dari shell.

Karena itu pendekatan yang benar adalah:

inotifywait -m --exclude "[^j].$|[^s]$" /path -e create -e moved_to |
    while read dir action file; do
        echo "The file '$file' appeared in directory '$dir' via '$action'"
    done

Catat .yang diperlukan setelah [^j]untuk memastikan bahwa pertandingan diterapkan dalam posisi kedua dari belakang, dan juga bahwa |karakter (mewakili boolean ATAU yang disebutkan di atas) tidak boleh melarikan diri di sini karena --excludemengambil POSIX diperpanjang regular expressions.

Adam Spires
sumber