LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash script has errors (https://www.linuxquestions.org/questions/programming-9/bash-script-has-errors-769804/)

smeezekitty 11-17-2009 07:54 PM

Bash script has errors
 
First, i am a newbie with bashscripts.
I wrote a bash script that is suppose to check if two files have equal checksome; but it has errors.
here are the errors :
Code:

./chk.sh: line 2: [pw: command not found
./chk.sh: line 2: ./pw: Permission denied
./chk.sh: line 9: [Files - and .cksm are identical: command not found
Files do not match
./chk.sh: line 17: end: command not found

and the script:
Code:

#/bin/bash
if ["$1" = "" || "$2" = ""]:
then
echo NO ARGS
killall $0
fi
md5sum $1 > .cksm
md5sum $2 | diff -s - .cksm > .cksm2
if ["$(more .cksm2)" = "Files $1 and $2 are identical"]:
then
echo Files match
else
echo Files do not match
fi
rm .cksm
rm .cksm2
end


gilead 11-17-2009 08:26 PM

You could try this:
Code:

#/bin/bash
if [[ "$1" = "" || "$2" = "" ]]
then
        echo NO ARGS
        exit 1
fi
diff -s <(md5sum $1 | awk '{print $1}') <(md5sum $2 | awk '{print $1}')

The output is a little messy, it talks about file descriptors instead of the file names.

I'd suggest reading the Advanced Bash Scripting Guide, it's got a range of techniques and good explanations.

ghostdog74 11-17-2009 08:31 PM

you can just use cmp
Code:

$ cmp file1 file2
$ echo $? #0 means equal


smeezekitty 11-17-2009 09:37 PM

Quote:

Originally Posted by ghostdog74 (Post 3760717)
you can just use cmp
Code:

$ cmp file1 file2
$ echo $? #0 means equal


doesnt actually compare the checksome.

smeezekitty 11-17-2009 09:52 PM

This works, any suggestions on how to improve it? code looks messy.
Code:

#!/bin/bash
if [[ "$1" = "" || "$2" = "" ]]
then
echo NO ARGS
exit
fi
md5sum $1 > .cksm
md5sum $2 | diff - .cksm > .cksm2
if ["$(more .cksm2)" = ""];
then
clear;echo Files match
else
clear;echo Files do not match
fi
rm .cksm
rm .cksm2
end


ghostdog74 11-17-2009 09:57 PM

Quote:

Originally Posted by smeezekitty (Post 3760757)
doesnt actually compare the checksome.

comparing checksum is the same as comparing file contents. if you really want to compare checksum,
Code:

$ md5sum file1 file2 | uniq -d -w32 |wc -l
if the result is 1, then they are the same.

ta0kira 11-17-2009 10:01 PM

Your problem is that you don't have spaces after [ and before ]; that means the shell concatenates what's next to it, preventing it from finding an appropriate command.
Kevin Barry

PS Why do you end lines with :?

smeezekitty 11-17-2009 10:12 PM

Quote:

Originally Posted by ghostdog74 (Post 3760773)
comparing checksum is the same as comparing file contents. if you really want to compare checksum,
Code:

$ md5sum file1 file2 | uniq -d -w32 |wc -l
if the result is 1, then they are the same.

wow that works good, i did not even know about the uniq command.

smeezekitty 11-17-2009 10:14 PM

Quote:

Originally Posted by ta0kira (Post 3760778)
Your problem is that you don't have spaces after [ and before ]; that means the shell concatenates what's next to it, preventing it from finding an appropriate command.
Kevin Barry

I am used to C where spaces dont matter much
Quote:


PS Why do you end lines with :?
A site online showed it with a :

bartonski 11-17-2009 11:16 PM

Quote:

Originally Posted by smeezekitty (Post 3760783)
I am used to C where spaces dont matter much
A site online showed it with a :

Interesting. ':' is equivalent to 'true' in the shell (both are generally shell builtins). I'm interested what the site that you picked that up from had in mind.

ta0kira 11-18-2009 12:15 AM

Quote:

Originally Posted by bartonski (Post 3760843)
Interesting. ':' is equivalent to 'true' in the shell (both are generally shell builtins). I'm interested what the site that you picked that up from had in mind.

That's only if it's the command, though. Could be a typo for ;.
Kevin Barry

bartonski 11-18-2009 10:32 AM

Quote:

Originally Posted by ta0kira (Post 3760891)
That's only if it's the command, though. Could be a typo for ;.
Kevin Barry

true, it could be a typo, but you can also do something like this:

Code:

while :
do
    echo "I am in an infinite loop."
done

I'm interested to know if smeezekitty ran across a more sophisticated version of this.

catkin 11-18-2009 10:51 AM

Quote:

Originally Posted by smeezekitty (Post 3760772)
This works, any suggestions on how to improve it? code looks messy.
Code:

#!/bin/bash
if [[ "$1" = "" || "$2" = "" ]]
then
echo NO ARGS
exit
fi
md5sum $1 > .cksm
md5sum $2 | diff - .cksm > .cksm2
if ["$(more .cksm2)" = ""];
then
clear;echo Files match
else
clear;echo Files do not match
fi
rm .cksm
rm .cksm2
end


As already posted there are neater ways of solving the problem but here are some suggestions about the shellscript itself in case they are of any interest. Mostly indentation so the logic/functional flow stands out. Also
  • changed "" to '' (heuristic: never use double quotes where single quotes will do)
  • escaped exit (with \exit) to defend against exit being an alias rather than the intended built-in
  • removed final "end" command (what did it do?)
Code:

#!/bin/bash
if [[ "$1" = '' || "$2" = '' ]]; then
    echo NO ARGS
    \exit
fi

md5sum $1 > .cksm
md5sum $2 | diff - .cksm > .cksm2

if [[ "$(more .cksm2)" = '' ]]; then
    clear; echo Files match
else
    clear; echo Files do not match
fi

rm .cksm
rm .cksm2

You could add error traps to ensure that $1 and $2 are readable files.

gnashley 11-18-2009 11:13 AM

Ending the script with a ':' is equivalent to having the last line of the script be:
exit 0
Having it at the end of each line will give each line of code an exit status of '0' which is probably not a good thing -I mean if you do error checking after running a line of code, having ':' at the end would destroy whatever exit code the line of code ahd generated.

smeezekitty 11-18-2009 12:59 PM

Quote:

Originally Posted by catkin (Post 3761473)
As already posted there are neater ways of solving the problem but here are some suggestions about the shellscript itself in case they are of any interest. Mostly indentation so the logic/functional flow stands out. Also
  • changed "" to '' (heuristic: never use double quotes where single quotes will do)
  • escaped exit (with \exit) to defend against exit being an alias rather than the intended built-in
  • removed final "end" command (what did it do?)
Code:

#!/bin/bash
if [[ "$1" = '' || "$2" = '' ]]; then
    echo NO ARGS
    \exit
fi

md5sum $1 > .cksm
md5sum $2 | diff - .cksm > .cksm2

if [[ "$(more .cksm2)" = '' ]]; then
    clear; echo Files match
else
    clear; echo Files do not match
fi

rm .cksm
rm .cksm2

You could add error traps to ensure that $1 and $2 are readable files.

Code:

./chk.sh chk.sh hello
<Clears screen>
Files do not match
bash: ./chk.sh: line 17: warning no 'end' statement at EOF
./chk.sh chk.sh chk.sh
<Clears screen>
Files match
bash: ./chk.sh: line 17: warning no 'end' statement at EOF
./chk.sh
NO ARGS



All times are GMT -5. The time now is 06:37 PM.