Execute script/program when file changes

1,313

Solution 1

one of your options is the inotify subsystem of the linux kernel:

inotify is a Linux kernel subsystem that acts to extend filesystems to notice changes to the filesystem, and report those changes to applications

but since inotify is kernel-land, you need something in user-space to actually use it:

The inotify cron daemon (incrond) is a daemon which monitors filesystem events and executes commands defined in system and user tables. It's use is generally similar to cron(8).

Gamin is a monitoring system for files and directories that independently implements a subset of FAM, the File Alteration Monitor. Running as a service, it allows for the detection of modifications to a file or directory. gam_server functions as a daemon for Gamin.

inoticoming - trigger actions when files hit an incoming directory

there was an answer to a similar question on askubuntu:

https://askubuntu.com/a/43848/1223

Solution 2

Another quick and dirty way to do this is to use inotifywait from the inotify-tools package (on fedora).

I like this method better because you can do it all from a single bash command line. I often use this when I'm writing small programs to see the results of what I just saved.

while [[ 1 ]]; do inotifywait -e modify <filename>; make && ./helloworld; done

Solution 3

I would argue that a mechanism for this within a shell script is a perfectly adequate solution and that a mechanism for that on operating system basis (so that I don't have to manually run a background program) just means putting that solution in a process manager like s6, runit, a systemd unit, or even an inittab entry if you're on a sysvinit system.

Regardless of the mechanism for keeping it running, I like entr for watching files. Simple, to the point, composable (e.g. trivial to put in a process manager).

Here's a script for watching /path/to/file and running /usr/local/bin/do_stuff when it changes:

#!/bin/bash
exec entr /usr/local/bin/do_stuff < <(echo /path/to/file)

That's all there is to it. Put that in the run file of runit or s6, put it in the ExecStart line of a systemd unit, or call that script from a line in inittab. Although if you put it in inittab you probably want to add a sleep somewhere, as sysvinit doesn't rate-limit processes that fail immediately due to misspellings, missing files or such.


Why not just echo /path/to/file | entr /usr/local/bin/do_stuff? When running under process management, it's important for the managed process to be directly under the supervisor, so that it behaves correctly under e.g. shutdown. If the shell runs under the supervisor, the shell will catch any TERM, INT or KILL signals rather than the process it is running, and it won't pass them along. Or, it will exit and leave the process orphaned. exec removes the shell from the process chain. (exec on the right side of the | makes no difference)

Or just use a shell that never puts itself in the middle, execline:

#!/bin/execlineb
pipeline -d {
  echo /path/to/file
} entr /usr/local/bin/do_stuff
Share:
1,313

Related videos on Youtube

briantaurostack7
Author by

briantaurostack7

Updated on September 18, 2022

Comments

  • briantaurostack7
    briantaurostack7 over 1 year

    Which is the recommended way to store images .Should it be stored in server or in cloud and how should it be retrieved to the client side in an Ecommerce web application which uses angular JS in client side and spring MVC4 hibernate 4 in server side. 1]DO I have to convert each image into bytes and send it to client from server with a seperate servlet image handler 2]IS there any other way 3] i am able to get the images in client side to server and server can store the images in public directory like d drive but I am not able to access a public directory which is situated in my d drive within client side What should I do?

    • Scary Wombat
      Scary Wombat about 8 years
      what is wrong with the standard <img src=...> tag
    • briantaurostack7
      briantaurostack7 about 8 years
      cannot access the dynamically loaded image
  • cyphorious
    cyphorious over 12 years
    Just to let you know: I now use inotify in combination with incron, which works perfectly fine for me. I'm aware that incron is still in alpha phase but it does a really well job. Thank you very much for this great advise!
  • briantaurostack7
    briantaurostack7 about 8 years
    Can i have an example code cause right now i have 1000 images and the images are dynamically loaded by vendors so when client tries to access the image since the war file is already deployed i cannot access the stored images in tomcat 7 so i want to know whether i have to send the images one by one from server to client or simply sending the url where the image is located is enough
  • Ankit Pundhir
    Ankit Pundhir about 8 years
    I think you can try by sending urls of images. If you dont have security concerns over images then you can directly share url of images inside a public directory. Also set directory accessibility to false.
  • briantaurostack7
    briantaurostack7 about 8 years
    But i am not able to access a public directory witch is situated in my d drive within client side .