Övervaka filsystemhändelser i Linux för automatisering
Den här guiden visar hur du kan utnyttja Linux filsystemhändelser, även kallade ”inotify”, för att få notifikationer varje gång en fil dyker upp i en specificerad katalog. Dessa händelser kan fungera som startpunkter för att automatisera återkommande uppgifter på ditt system.
Vi ska skapa ett skript som kontinuerligt bevakar en mapp och reagerar på nya filer som läggs till. Varje upptäckt fil kommer att komprimeras med gzip och sedan flyttas till en annan mapp. Skriptet använder inotify-undersystemet via ett verktyg som heter inotify-tools. Låt oss först installera verktygen och testa dem.
Installation av inotify-tools och gzip
Om du använder Ubuntu eller en annan Debian-baserad distribution, använd apt-get för att installera det nödvändiga paketet. För andra Linux-distributioner, använd den pakethanterare som är specifik för din distribution.
sudo apt-get install inotify-tools gzip
Experimentera med inotify-verktyg
Låt oss börja med att undersöka en katalog och se vilka händelser som genereras när nya filer skapas. Vi kommer att använda verktyget `inotifywatch`, som ingår i inotify-tools. Skapa en ny mapp med namnet ”inkommande”:
mkdir incoming
Starta övervakningen av katalogen genom att köra följande kommando:
inotifywatch -v incoming
Detta kommando instruerar inotify att hålla koll på alla filsystemhändelser i katalogen ”inkommande”. Alternativet `-v` gör att verktyget visar extra information om sina operationer. Eftersom vi inte har angett en timeout (med `-t`), kommer kommandot att fortsätta registrera händelser tills vi avbryter det med CTRL+C. Din terminal bör nu se ungefär så här:
Öppna ett nytt terminalfönster (eller flik) och navigera till katalogen ”inkommande”. Använd kommandot `touch` för att skapa en ny fil med namnet ”nyfil”:
cd incoming/ touch nyfil
Återgå till det första terminalfönstret och stoppa inotifywatch genom att trycka på CTRL+C.
Du kommer att se en tabell med händelser på konsolen, som visar ”create”, ”open”, ”attrib” och ”close_write”. Dessa fyra händelser inträffade när vi använde `touch` för att skapa filen, justera dess attribut, öppna den för att skriva en nullterminator och sedan stänga den. Dessa är bara några av de många händelser som kan bevakas med inotify. Du kan se en fullständig lista på inotifywatchs man-sida.
För vårt ändamål är vi endast intresserade av två händelser:
- ”create” – när en ny fil skapas i målkatalogen.
- ”moved_to” – när en fil flyttas från en annan plats till målkatalogen.
Låt oss försöka igen med inotifywatch, men den här gången instruerar vi den att endast övervaka de två nämnda händelserna. Kör detta kommando i det första terminalfönstret:
inotifywatch -v -e create -e moved_to incoming
I det andra terminalfönstret, eller fliken, ska vi nu skapa en ny fil, ändra dess innehåll och sedan flytta en fil från en annan plats till målkatalogen. Alla dessa kommandon körs från din hemkatalog.
touch incoming/skapad echo Testing123 >> incoming/skapad touch /tmp/skapad2 mv /tmp/skapad2 incoming/
Återgå till det första terminalfönstret och stoppa inotifywatch med CTRL+C. Du bör se följande utdata:
Endast två händelser registrerades: skapandet av filen ”skapad” och flyttningen av filen ”skapad2”. Allt annat, som att ändra ”skapad”, ignorerades.
Övervaka en katalog och utför en åtgärd
Nu när vi vet vilka händelser vi vill följa kan vi använda `inotifywait` för att pausa exekveringen tills en fil skapas eller flyttas till vår målkatalog. Vi kommer att använda samma argument som i `inotifywatch`, samt specificera hur vi vill att filnamnet ska formateras för att användas i vår uppgift.
Innan vi börjar behöver vi en mapp för filer som redan har behandlats. Skapa en mapp med namnet ”behandlade”:
mkdir processed
Skapa sedan ett nytt skript med namnet ”watch-incoming.sh” och lägg till nedanstående innehåll:
#!/bin/bash TARGET=~/incoming/ PROCESSED=~/processed/ inotifywait -m -e create -e moved_to --format "%f" $TARGET | while read FILENAME do echo Detected $FILENAME, moving and zipping mv "$TARGET/$FILENAME" "$PROCESSED/$FILENAME" gzip "$PROCESSED/$FILENAME" done
Skriptet kör `inotifywait` med `-m`-alternativet, vilket gör att övervakningen pågår tills den manuellt avbryts. Varje gång en ny händelse detekteras skickas filnamnet till `read` och placeras i variabeln ”FILENAME”. Koden i `while`-loopen körs, där filen först flyttas till katalogen ”behandlade” och sedan komprimeras med gzip. Den ursprungliga filen ersätts av den komprimerade, vars filnamn slutar med ”.gz”.
Låt oss ge skriptet körrättigheter och köra det från din hemkatalog.
chmod u+x watch-incoming.sh ./watch-incoming.sh
Öppna det andra terminalfönstret och skapa en ny fil i katalogen ”inkommande”. Lista innehållet i både ”inkommande” och ”behandlade” för att se effekterna av den upptäckta händelsen:
Den ursprungliga textfilen vi lade till i ”inkommande” detekterades av skriptet, kopierades till ”behandlade” och komprimerades sedan.
Vi kan nu göra flera spännande saker tack vare förmågan att övervaka nya filer som dyker upp i en katalog. Exempelvis kan vi lägga till en vattenstämpel till bildfiler, komprimera videor till mp4-format eller till och med ladda upp varje ny fil till en Amazon S3-bucket. Det här skriptet är en bra startpunkt för att skapa dina egna arbetsflöden och automatisera återkommande uppgifter på ditt system.