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).