Home > Mobile >  bash check for new directories and do a diff
bash check for new directories and do a diff

Time:10-16

I need to write a Bash script to check if there are any new folders in a path, if yes do something and if not then simply exit.

My thinking is to create a text file to keep track of all old folders and do a diff, if there something new then perform action. Please help me achieve this:

I've tried to use two file tracking but I don't think I've got this right.

The /tmp/ folder has multiple sub folders

#/bin/sh
BASEDIR=/tmp/
cd $BASEDIR
ls -A $BASEDIR >> newfiles.txt
DIRDIFF=$(diff oldfiles.txt newfiles.txt | cut -f 2 -d "")
for file in $DIRDIFF
do
  if [ -e $BASEDIR/$file ]
  then echo $file
  fi
done

CodePudding user response:

It is not clear if you are interested in files or in folders. As you use ls -A let's assume you are interested in both. Let's assume too that you do not have file or folder names with newlines in them.

Do not process ls output, it is for humans only. Prefer find. Then, simply sort the old and new lists with sort and compare them with comm, keeping only the lines found in the new list but not in the old list (man comm will tell you why the -13 option does this):

#!/bin/sh
BASEDIR=/tmp/
cd $BASEDIR
find . | sort > newfiles.txt
comm -13 oldfiles.txt newfiles.txt
mv newfiles.txt oldfiles.txt

This will explore the complete hierarchy under the starting point, and consider any file, directory, link...

Thanks to find options you can be a bit more specific about what objects you want to compare. For instance, if you are really interested only in directories:

find . -type d | sort > newfiles.txt

will list only the sub-directories. If you do not want to explore the complete hierarchy under the starting point but only the current level:

find . -maxdepth 1 -type d | sort > newfiles.txt

CodePudding user response:

Generally don't use ls in scripts. Here is a simple refactoring which avoids it.

#!/bin/sh
printf '%s\n' /tmp/.[!.]* /tmp/* >newfiles.txt
if cmp -13 oldfiles.txt newfiles.txt | grep .; then
    rc=0
    rm newfiles.txt
else
    rc=$?
    mv newfiles.txt oldfiles.txt
fi
exit "$rc"

Using comm instead of diff simplifies processing somewhat (the wildcard should expand the files in sorted order, so the requirement for sorted input will be satisfied) and keeping the files in the current directory (instead of in /tmp) should avoid having the script trigger itself. The output from comm will be the new files, so there is no need to process it further. The grep . checks if there are any output lines, so that we can set the exit status to reflect whether or not there were new entries.

Your script looks for files, not directories. If you really want to look for new directories, add a slash after each wildcard expression:

printf '%s\n' /tmp/.[!.]*/ /tmp/*/ >newfiles.txt

This will not notice if an existing file or directory is modified. Probably switch to inotifywait if you need anything more sophisticated (or perhaps even if this is all you need).

  •  Tags:  
  • bash
  • Related