I wrote a find command, which finds the files, but excludes other files/directories. I did echo this code and copied it. If I paste it in the terminal, it works. Some files were excluded. But if I execute it from the script, it does not work as expected.
I tried to escape my variables, quote them, between brackets like $()
or ${}
but nothing worked.
My find code looks like this:
find ${StartDirs[*]} $pat -print
In fact it will be executed like:
find ./bin -wholename './bin/backup2' -prune -o -wholename './bin/backup3' -prune -o -print
The second code above works in the terminal but not in the script. What did I do wrong?
For more info I will try to paste necessary code below I am trying to make a backup and want to do that with find and cp. Most code of my script are omitted. I think the code below is the necessary minimal code for this problem.
StartDirs=();
ExcludedFiles=(); #files/directories which needs to be excluded
#check and store excluded files
CheckExcludedFile(){ #this function will be called over and over again by another function (getopts). It depends on the chain of -x options. With the -x option I can decide which file i want to exclude. The Getopts function is also omitted.
exclFile=`find $1 2>/dev/null | wc -l`
if [ $exclFile -lt 1 ]; then
echo $FILEMAPNOTEXIST | sed 's~-~'$1'~g' # FILEMAPNOTEXIST is a variable from another script with error messages
exit 0
else
ExcludedFiles+=($1) #add excluded file/dir path to array
fi
}
MakeBackup(){
for i in ${ExcludedFiles[*]}
do
s=" -wholename $i -prune -o"
pat=$pat$s
done
# the code above edits the array elements of the EcludedFIles[]
#For example by calling the script with the -x option (-x fileA -x fileB -x fileC) wordt als volgt: -wholename 'fileA' -prune -o -wholename 'fileB' -prune -o -wholename 'fileC' -prune -o.
#the pat variable will be used for the find command to ignore files/directories
mkdir -p ~/var
echo "Start-time $(date '+%F %T')" >> ~/var/dq.log
find ./bin -wholename './bin/backup2' -prune -o -wholename './bin/backup3' -prune -o -print
#the code above should work like in terminal. That is not the case..
# find ${StartDirs[*]} $pat -print #this should work also.
# cp -av ${StartDirs[@]} $Destination >> ~/var/dq.log find command not working therefore this rule is commented
echo "end-time $(date '+%F %T')" >> ~/var/dq.log
}
The expected result should simply be some files/directories being excluded if given.
If a full script is necessary, let me know.
The command find ./bin -wholename './bin/backup2' -prune -o -wholename './bin/backup3' -prune -o -print
should work as intended, provided the current directory is directly above bin/
. This may be the cause of your problems: If in the real script you assemble path names which do not match the prefixes in the found paths then e.g. the prune will not work. Example: You have a dir /home/me
; in it is bin/backup2/
, bin/backup3/
and stuff-to-backup/
. Now if you are in /home/me
and execute find .
it finds e.g. ./bin/backup2
which will be pruned.
But if you put this in a script and call the script with path arguments, e.g. /home/me
, it will find the same files but the paths will be different, e.g. /home/me/bin/backup2
, and will not prune it because it does not match the supplied exclude pattern, even though they are the same files. Likewise no patterns supplied with -wholename
will be found. Here is a question which addresses this problem.