views:

561

answers:

4

I'm trying to write a shell script which will compare two files, and if there are no differences between then, it will indicate that there was a success, and if there are differences, it will indicate that there was a failure, and print the results. Here's what I have so far:

result = $(diff -u file1 file2)

if [ $result = "" ]; then
    echo It works!
else
    echo It does not work
    echo $result
fi

Anybody know what I'm doing wrong???

+4  A: 
result=$(diff -u file1 file2)

if [ $? -eq 0 ]; then
    echo "It works!"
else
    echo "It does not work"
    echo "$result"
fi

Suggestions:

  • No spaces around "=" in the variable assignment for results
  • Use $? status variable after running diff instead of the string length of $result.
  • I'm in the habit of using backticks for command substitution instead of $(), but @Dennis Williamson cites some good reasons to use the latter after all. Thanks Dennis!
  • Applied quotes per suggestions in comments.
  • Changed "=" to "-eq" for numeric test.
Bill Karwin
I like backticks, too, but this kind of 'matter of taste' thing may get you downvoted by some zealots.
pavium
This is cleaner than my answer, +1
Steve B.
+1 from me too as it explain more things and look nicer. One problem though, "!" cannot be use without escape or non process wrapping ('').
NawaMan
Apologies, I reversed the explanation of "`=`" and "`-eq`" in the test syntax. I have removed my error!
Bill Karwin
Don't use backticks. It's not just a matter of taste - nested commands, nested quoting, readability, etc., are all better: http://mywiki.wooledge.org/BashFAQ/082
Dennis Williamson
I looked up the man page for test, and it looks to me as if the "-eq" is for numeric tests... Thanks, but I'm still not sure how to write the part that goes between the [ ] in the If...
Use "$result" instead of $result. Applies to original test (which would work with "$result") and answer.
Jonathan Leffler
johnathan, so you're saying it should be: if [ "$?" = 0 ];?
I think he's saying to use `[ "$result" ]` which returns true when result is non-blank and false when result is blank. You also have to reverse your then and else clauses. I just tried this and it works. But I still prefer to use `$?`.
Bill Karwin
And it should not be necessary to put quotes around `$?` because that's a shell builtin variable that is always an integer. Never blank, and never contains spaces.
Bill Karwin
+3  A: 

First, you should wrap strings being compared with quotes.

Second, "!" cannot be use it has another meaning. You can wrap it with single quotes.

So your program will be.

result=$(diff -u file1 file2)

if [ "$result" == "" ]; then
    echo 'It works!'
else
    echo It does not work
    echo "$result"
fi

Enjoy.

NawaMan
$result needs to be in double quotes-bash doesn't evaluate stuff in single quotes, so it's actually evaluating the literal string $result here. It works with double quotes, though.
Steve B.
Right that is my quick type mistake ... I will fix that.
NawaMan
If you're using Bash or ksh, you can use double brackets [[ ]] and you can often avoid quoting and escaping, plus you get access to more tests including regex matching: http://mywiki.wooledge.org/BashFAQ/031
Dennis Williamson
Thanks, I wonder that before. Just know now. :D
NawaMan
A: 

Since you need results when you fail, why not simply use 'diff -u file1 file2' in your script? You may not even need a script then. If diff succeeds, nothing will happen, else the diff will be printed.

Ashwin
A: 

bash string equivalence is "==". -n is non-zero string, -z is zero length string, wrapping in quotes because the command will complain if the output of diff is longer than a single string with "too many arguments". so

if [ -n "$(diff $1 $2)" ]; then
    echo "Different"
fi

or

if [ -z "$(diff $1 $2)" ]; then
    echo "Same"
fi
Steve B.
But how to output the result when they are different?
Bill Karwin