11

I want to watch any changes to a file xyz.txt and email me the entire file whenever there is a change. Is there One Liner (or a few lines shell script) for this?

Update:

# Check if my.cnf has been changed in the last 24 hours
# if yes, as in the following case, simply send the file
# if it has not been changed in the last 24 hours, do nothing.

# find /etc/ -name my.cnf -mtime 0
/etc/my.cnf

# cat /etc/my.cnf | mail shantanu@company.com

Now if someone can show how to bind these two lines in a shell script or in 1 command.

shantanuo
  • 31,689
  • 78
  • 245
  • 403
  • You could use [`fswatch`](https://github.com/emcrisostomo/fswatch) which is cross platform and straightforward `fswatch -o my_file | xargs -n1 -I{} my_program` – Ulysse BN Dec 13 '18 at 23:29

6 Answers6

25

You could use inotifywait. It waits for changes to a file, and then executes a command (e.g. something like msmtp in your case).

igor
  • 2,090
  • 20
  • 32
10

You should look into inotify which can watch a file or directory and report changes.

Marcus Whybrow
  • 19,578
  • 9
  • 70
  • 90
4

Give this a try:

find /etc/ -name my.cnf -mtime 0 -exec sh -c 'cat {} | mail -E -s "file changed" shantanu@company.com' \;

The -E option to mail prevents it from sending messages with empty bodies (as would be the case if find returns nothing and cat outputs nothing.

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
3

inotify-hookable is a perl script that is quite easy to use for this purpose. For example,

inotify-hookable -f /path/to/file -c "latexmk -pdf /path/to/file" &
inotify-hookable -f /path/to/file -c "cp /path/to/file /path/to/copy" &

-f for the file to watch -c for the command to run

I had it watching a file in on a remote computer too, but inotify-hookable finished when the watched file was deleted prior to being updated.

I installed it from Debian. CPAN link: https://metacpan.org/pod/App::Inotify::Hookable

szabgab
  • 6,202
  • 11
  • 50
  • 64
1

As I've learnt from another question over at superuser (all credit due there):

entr (https://github.com/eradman/entr) provides a more friendly interface to inotify (and also supports *BSD & Mac OS X).

This watches a given file (or files) for changes and runs the command whenever (the instant) it changes. So you could do it like:

echo /etc/my.cnf | \
  entr sh -c 'cat /etc/my.cnf | mail -E -s "file changed" shantanu@company.com'

(PS. Credit to Denis's answer for the mail command)

artfulrobot
  • 20,637
  • 11
  • 55
  • 81
-2
#!/bin/ksh

ls -lt /usr/tip30/prtfile/asb270.prt|awk '{print $6$7$8}'|awk -F: '{print $1$2}'
 > /tmp/lastupdated.temp
read input_pid < /tmp/lastupdated.temp
echo "$input_pid"

while [ "$input_pid" -eq "`ls -lt /usr/tip30/prtfile/asb270.prt | awk '{print $6
$7$8}'|awk -F: '{print $1$2}'`" ]; do
   echo "file has not changed "
   sleep 30
done
echo "file changed `ls -lt /tmp/lastupdated.temp`"
rm /tmp/lastupdated.temp
halfer
  • 19,824
  • 17
  • 99
  • 186