I am writing a simple Bash script to detect when a folder has been modified.
It is something very close to:
ls -lR $dir > a
ls -lR $dir > b
DIFF=$(diff a b)
if [ $DIFF -ne 0 ]
then
echo "The directory was modified"
Unfortunately, the if statement prints an error: [: -ne: unary operator expected
I am not sure what is wrong with my script, would anyone please be able to help me?
Thank you very much!
Jary
ls -lR $dir > a
ls -lR $dir > b
DIFF=$(diff a b)
if [ "$DIFF" != "" ]
then
echo "The directory was modified"
fi
if ! diff -q a b &>/dev/null; then
>&2 echo "different"
fi
You are looking for the return value of diff
and not the output of diff
that you are using in your example code.
Try this:
diff a b
if [ $? -ne 0 ]; then
echo "The directory was modified";
fi
DIFF=$(diff -u <(find dir1/ -type f -printf '%P\n' | sort) <(find dir2/ -type f -printf '%P\n' | sort))
if [ "$DIFF" ]; then
echo "Directories differ"
# Do other stuff here
fi
This uses one of my favorite bashisms, the <()
process substitution.
The $DIFF
variable holds a printable difference. If you want to show it to the end user, be sure to double-quote it, e.g. echo "$DIFF"
.
If you want to only tell the user there was any difference, if can be shortened to something like [ "$(diff ...)" ] && echo "Difference found"
Note: I'm assuming the original question meant to have dir1
and dir2
to make a little more sense. If it was dir
at time 0 and then dir
at time 1, this approach obviously wouldn't work.
If you don't need to know what the changes are, cmp
is enough.
Plus you can play with the syntactical trick provided by and ||
:
cmp a b || echo 'The directory was modified'
The instruction may be interpreted as: "either a and b are equal, or i echo the message".
(The semantic of &&
and ||
must be handled with care, but here it's intuitive).
Just for the sake of readability, i actually prefer to put it on two lines:
cmp a b \
|| echo 'The directory was modified'
来源:https://stackoverflow.com/questions/3611846/bash-using-the-result-of-a-diff-in-a-if-statement