3

I have been trying to tackle this problem for a few days before resorting to a vague question. I'm aware of tools such as inotify however as part of an assignment i am not allowed to use tools that do it for you. I used watch -n 5 -d ls -l to visually show the changes. However this is not what i'm looking for. I would like to print the changes to the terminal when files within a directory get deleted, created, or renamed. I am not looking for an outright solution, just some suggestions on how i should try tackle this problem.

  • 3
    `inotify` IS the right tool – Gilles Quénot Oct 17 '17 at 17:51
  • Inotify does work perfectly but i am not allowed to use tools like that. – Declan Price Oct 17 '17 at 17:57
  • What's the problem with using `watch`? Also, if you really can't use watch, perhaps your own bash script could be created. How about a simple script that runs every X seconds, does a `ls`, dumps output to a file and `diff`s it with previously written file. Output of ls and diff can be customized as needed. – Vasan Oct 17 '17 at 18:09
  • If you have to use bash only, there's not much you can do. You'll need to call things like `watch` and `ls`, and there's absolutely no distinction between those tools and `inotifywait`, so you might as well use inotifywait. – William Pursell Oct 17 '17 at 19:13
  • To echo the other commentators, that's an odd and very difficult assignment. It seems like Bash-only is intended to be literal, i.e., meaning no external commands, e.g., requiring the use of shell globbing instead of running a command like `ls`. For such a complex task, Bash is not very practical. – Anthony Geoghegan Oct 17 '17 at 20:19

3 Answers3

0

The best way to accomplish this is probably by using the inodes of the files in the targeted directory as an identifier to track changes. For example, you could build a hash table when your script starts by storing the inode as the identifier and using the file name as the key. once the initial table is built, the program will loop back over the directory & table again checking for the following;

  • Has an inode disappeared? If so, the key that has an identifier == to that effected inode has been deleted.

  • Do the identifiers and keys still match up with the directory? if not then files have been renamed.

  • And finally, is there a new inode showing up in the directory? if so a new file has been created so we will need to add it and its filename to the table.

Hope this helps you out.

Kedar Brooks
  • 531
  • 5
  • 11
0

Do you need the change immediately?

If not, a bash script is enough, there should be a loop in the script, check all the files in the directory, if it is not the same with the last check, then output something, then continue.

Forward
  • 855
  • 7
  • 12
0

Well, not using the tools written for the intended purpose (e.g. inotifywait) does make things a bit more interesting.... What can tell you whether a file has been modified or not? (hint: how about something that can give a unique fingerprint of each file?) Not the fastest thing in the world, but a md5sum will certainly do that for you. A simple redirection of the results will do:

$ md5sum yourdir/* > yourdir.md5

How to notice if a file has been added, removed, or changed in some way? You would need a way to compare the checksums for each file at some given interval. You can simply use the --check option for md5sum, but that will not catch new or removed files, only changed files. What else could compare and identify any new, removed or changed files? diff comes to mind.

What if you create a new listing say:

$ md5sum yourdir/* > yourcheck.md5

and then call diff to compare the checksum listings?

$ diff yourdir.md5 yourcheck.md5

Based on the simple diff output you could determine if a file was added, removed, or changed. For the next iteration, you could simply copy yourcheck.md5 to yourdir.md5 (so it holds the current checksums for the directory) and then repeat your check at the next interval.

You can also use variations of options for diff to simply check for changes without creating output, etc. depending on how you want to handle the flow of you script.

Now this isn't the only way to approach the problem, but is can be a simple way to do it using only md5sum and diff.

You can do something very similar replacing md5sum with stat and storing file mod-times, etc. You will just have to see if there is any speed benefit to be gained using one verses the other. (though I suspect simply picking off the mod time for each file would be much quicker than generating a md5sum of each file)

There are many other ways to capture the state of the files in a directory. (for that matter, you can just redirect a directory listing that includes the date and time, e.g. ls -al into a file and diff that without relying on md5sum or stat to capture the same information in a different form). See what you can come up with.

The key will be to diff two versions of something. What... is up to you.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85