bash-3.00$ cat compare.sh #NOTE : 1.Filename must not have space for the script to work.
# 2.Script wont work if symlinks are there instead of proper filenames.
#!/bin/bash
#set -x
#############################VERIFYING THE EXISTENCE OF DUPLICATE FILENAMES IN THE SUPPLIED FILENAMES ###############
if [[ $# -lt 1 ]];then
echo "Usage : `basename $0` filename" 1>&2
exit 2
fi
awk '{f=$9;
for(i=10;i<=NF;i++)
f=f" "$i;
d[f]++;
}
END{
for(f in d)
if(d[f] > 1)
printf("file %s occurs %d times\n",f,d[f]);
}' `basename $1`
echo -e "Please remove the dupliacte entries,\
\nkeep the file with the latest timestamp and check again"
################################CHECKING SIZE,DATE,TIME,FILENAME WITH THE EXISTING FILES############################
status=0
cat $1 | awk '{print $(NF-4),"\t",$(NF-3),"\t",$(NF-2),"\t",$(NF-1),"\t",$(NF)}' | \
while read size mon day time filename; do
if [[ ! -f "$filename" ]]; then
echo "ERROR: no such file: $filename" >&2
status=1
else
filesize=$(ls -lrt "$filename" | awk '{print $5}')
if [[ "$size" != "$filesize" ]]; then
echo "ERROR: size mismatch: $filename" >&2
status=1
else
# filetime=$(ls -lrt "$filename" | awk '{print $6," ",$7," ",$8}')
actual_mon=$(ls -lrt "$filename" | awk '{print $6}')
actual_day=$(ls -lrt "$filename" | awk '{print $7}')
actual_time=$(ls -lrt "$filename" | awk '{print $8}')
if [[ "$mon $day $time" != "$actual_mon $actual_day $actual_time" ]]; then
echo "ERROR: date mismatch: $filename" >&2
status=1
fi
fi
fi
done
echo $status
if [[ "$status" -eq 0 ]];then
echo -e "\t\n\nSuccess! All the files are found and their size and timestamp is also matching with the existing files."
else
echo -e "\t\n\nFailure! Non-matching files are found or file doesn't exist."
fi
The value of status always remains 0.
How do i get the changed value from inside the while loop
bash-3.00$ cat compare.sh
#NOTE : 1.Filename must not have space for the script to work.
# 2.Script wont work if symlinks are there instead of proper filenames.
#!/bin/bash
#set -x
#############################VERIFYING THE EXISTENCE OF DUPLICATE FILENAMES IN THE SUPPLIED FILENAMES ###############
if [[ $# -lt 1 ]];then
echo "Usage : `basename $0` filename" 1>&2
exit 2
fi
awk '{f=$9;
for(i=10;i<=NF;i++)
f=f" "$i;
d[f]++;
}
END{
for(f in d)
if(d[f] > 1)
printf("file %s occurs %d times\n",f,d[f]);
}' `basename $1`
echo -e "Please remove the dupliacte entries,\
\nkeep the file with the latest timestamp and check again"
################################CHECKING SIZE,DATE,TIME,FILENAME WITH THE EXISTING FILES############################
status=0
cat $1 | awk '{print $(NF-4),"\t",$(NF-3),"\t",$(NF-2),"\t",$(NF-1),"\t",$(NF)}' | \
while read size mon day time filename; do
if [[ ! -f "$filename" ]]; then
echo "ERROR: no such file: $filename" >&2
status=1
else
filesize=$(ls -lrt "$filename" | awk '{print $5}')
if [[ "$size" != "$filesize" ]]; then
echo "ERROR: size mismatch: $filename" >&2
status=1
else
# filetime=$(ls -lrt "$filename" | awk '{print $6," ",$7," ",$8}')
actual_mon=$(ls -lrt "$filename" | awk '{print $6}')
actual_day=$(ls -lrt "$filename" | awk '{print $7}')
actual_time=$(ls -lrt "$filename" | awk '{print $8}')
if [[ "$mon $day $time" != "$actual_mon $actual_day $actual_time" ]]; then
echo "ERROR: date mismatch: $filename" >&2
status=1
fi
fi
fi
done
echo $status
if [[ "$status" -eq 0 ]];then
echo -e "\t\n\nSuccess! All the files are found and their size and timestamp is also matching with the existing files."
else
echo -e "\t\n\nFailure! Non-matching files are found or file doesn't exist."
fi
Check out Variable Scope in Bash (NuclearDonkey.net) for one of several possible solutions here. Essentially, the issue is that you're modifying variables in a sub-process. You'll either need some inter-process trickery, or you'll have to modify your code to eliminate the direct use of the pipeline.
Also, please use [code] tags, as they make things much, much easier to read.
This is an issue caused with the way bash implements pipes. When piping input to a while, I believe that bash executed the while in a child processes which causes any changes to variables inside of the while to be lost.
This is one reason I prefer kshell over bash. If you have a modern kshell, I suggest you use it. If not then try writing your output to a temp file and reading it into the while.
x=0
ls | while read f
do
x=$(( $x + 1 ))
printf "in loop: $x\n"
done
printf "after loop: $x\n"
ls >/tmp/ls
x=0
while read f
do
x=$(( $x + 1 ))
printf "in loop: $x\n"
done </tmp/ls
printf "after second loop: $x\n"
Try this in both shells to see the difference. Ksh gets the answer right after the loop both times.
Here is a little BASH trick to avoid these problems...
#!/bin/bash
function myLoop()
{
echo $1 |
while read WORD
do
echo $WORD|egrep "[0-9]" 2>/dev/null 1>/dev/null
RETVAL=$?
echo "Something to the screen..." >&2
echo $RETVAL
done
}
echo RETVAL=$(myLoop $1)
The basic idea is to echo the value as a function output. This output can then be captured as whatever variable you want.