Watch a file for change

2020-05-21 06:09发布

问题:

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.

回答1:

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.



回答2:

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



回答3:

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



回答4:

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



回答5:

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

entr (http://entrproject.org/) 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)



回答6:

#!/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