Skip to content

Instantly share code, notes, and snippets.

@pratikmallya
Created May 9, 2024 15:32
Show Gist options
  • Save pratikmallya/ab230b6579f7d03820b57681d574fecb to your computer and use it in GitHub Desktop.
Save pratikmallya/ab230b6579f7d03820b57681d574fecb to your computer and use it in GitHub Desktop.
A tail implementation using inotify (fsnotify)
package main
import (
"bufio"
"fmt"
"log"
"os"
"github.com/fsnotify/fsnotify"
)
func main() {
// Create new watcher.
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
if err = watcherFunc(watcher, "foo"); err != nil {
log.Fatal(err)
}
}
func watcherFunc(watcher *fsnotify.Watcher, paths ...string) error {
var filemap = make(map[string]*bufio.Reader)
for _, path := range paths {
fd, err := os.Open(path)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
}
filemap[path] = bufio.NewReader(fd)
err = watcher.Add(path)
if err != nil {
return fmt.Errorf("error adding path to watcher: %w", err)
}
}
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return fmt.Errorf("something went wrong")
}
if event.Has(fsnotify.Write) {
log.Println("modified file:", event.Name)
data, err := filemap[event.Name].ReadString('\n')
if err != nil {
return fmt.Errorf("error reading file: %w", err)
}
log.Println("file contents:", data)
}
case err := <-watcher.Errors:
return fmt.Errorf("error reading from watcher: %w", err)
}
}
}
@pratikmallya
Copy link
Author

A more robust implementation is in this package. This is a really simple demo of how to use inotify to only read a file when it changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment