2

I find it odd as I managed to get different md5sum using the exact same file from the same directory. The output as below:

[root@testlabs Config]# ls  
Backup_Files  
hostname1-config.uac  
hostname2-config.uac  
hostname3-config.uac  
[root@testlabs Config]# ls hostname1-config.uac | md5sum  
2a52f0eb11f6478a4f8aeee1c0ac90dd  -      
[root@testlabs Config]# md5sum hostname1-config.uac  
d41d8cd98f00b204e9800998ecf8427e  hostname1-config.uac  

May I know which is the correct way to get the correct md5sum result? Thank you.

I did this to compare the MD5 of two files (original file and backup copy file). The naming convention of the original file is hostname1-config.uac, while the backup file is hostname1-201411071649.uac; but they are just copies (cp -p).

First Method

(Does not work)

 #!/bin/bash
 # ...
 #
 ls hostname1-config.uac | md5sum hostname1-config.uac > /tmp/md5sum.tmp
 ARCHIVE_DIR="/tmp/Archive"
 FULL_HOSTNAME=`/bin/sort -d /tmp/full_hostname.tmp`
 TIMESTAMP=`/bin/date +%Y%m%d%H%M -r $FULL_HOSTNAME`

 for HOSTNAME in `/bin/sort -d /tmp/hostname.tmp`
 do
     ls $ARCHIVE_DIR | grep -i --text $HOSTNAME-$TIMESTAMP.uac | md5sum -c /tmp/md5sum.tmp >> /tmp/md5sum2.tmp
 done

Second Method

(Worked perfectly in Command-line but not in script)

In Command-Line

[root@testlabs Config]# md5sum hostname1-config.uac
ca3434263400ea2b4ffbc107ef729b8a  hostname1-config.uac
[root@testlabs Config]# md5sum hostname1-config.uac > md5.tmp
[root@testlabs Config]# cd /tmp/Archive
[root@testlabs Archive]# md5sum hostname1-config.uac
ca3434263400ea2b4ffbc107ef729b8a  hostname1-config.uac
[root@testlabs Archive]# echo 'Tampered!' > hostname1-config.uac
[root@testlabs Archive]# cat hostname1-config.uac | md5sum -     c /Network_Backup/Config/md5.tmp
hostname1-config.uac: FAILED
md5sum: WARNING: 1 of 1 computed checksum did NOT match
[root@testlabs Archive]# rm -f hostname1-config.uac
[root@testlabs Archive]# cd /tmp/Config
[root@testlabs Config]# cp -p hostname1-config.uac /tmp/Archive
[root@testlabs Config]# cd /tmp/Archive
[root@testlabs Archive]# cat hostname1-config.uac | md5sum -c /Network_Backup/Config/md5.tmp
hostname1-config.uac: OK

In Script

#!/bin/bash
# ...
#
CONFIG_DIR="/tmp/Config"
ARCHIVE_DIR="/tmp/Archive"
HOSTNAME=`/bin/sort -d /tmp/hostname.tmp`
FULL_HOSTNAME=`/bin/sort -d /tmp/full_hostname.tmp`
TIMESTAMP=`/bin/date +%Y%m%d%H%M -r $FULL_HOSTNAME`

cd $CONFIG_DIR
md5sum $FULL_HOSTNAME > /tmp/md5sum.tmp
cd $ARCHIVE_DIR
cat $HOSTNAME-$FILE_TIMESTAMP.uac | md5sum -c /tmp/md5sum.tmp >> /tmp/md5sum2.tmp

The returned result in /tmp/md5sum2.tmp:
hostname1-config.uac: FAILED open or read

2

The response FAILED open or read happens when the file specified in the md5 checksum file (md5sum.tmp in your case) does not exist.

For example.

[user@localhost tmp]$ cd /tmp/testfolder
[user@localhost testfolder]$ touch dog
[user@localhost testfolder]$ md5sum dog > /tmp/md5sum.tmp
[user@localhost testfolder]$ md5sum -c /tmp/md5sum.tmp
dog: OK
[user@localhost testfolder]$ cd ..
[user@localhost tmp]$ md5sum -c /tmp/md5sum.tmp
md5sum: dog: No such file or directory
dog: FAILED open or read
md5sum: WARNING: 1 listed file could not be read

Note that I believe the md5sum program does not look at the standard input when passed the -c option. It simply looks at the checksums in the file specified by the -c option. If they exist and the filename matches, than it compares it and all is happy.

While there is probably a better way, storing the result of two separate md5sums in a variable and then comparing them with an if statement is probably the approach I would take.

Kind of like this.

#!/bin/bash
firstfile=`cat dog | md5sum `
# alternately could have used firstfile=$(md5sum < dog ) to ovoid UUOC
secondfile=`cat mouse | md5sum `
if [ "$firstfile" == "$secondfile" ]; then
    echo "They Match!"
else
    echo "They Don't Match!"
fi
  • @R Schultz Yup this sounds workable. Let me try it out after my lunch. Thanks a lot! – Win.T Nov 17 '14 at 5:29
  • @R Schultz, it worked perfectly. Thank you very much! :) – Win.T Nov 17 '14 at 6:17
  • Thanks for that edit @R Schultz. In my defense, I'd posted just before going to bed :). Why are you suggesting the OP use cat though? That looks like a classic UUOC. Why not firstfile=$(md5sum doc)? – terdon Nov 17 '14 at 12:07
  • 1
    @terdon... regarding the UUOC, two reasons. 1) using the $(md5sum doc) method adds the filename to the end of the result vice -. Since the filenames are different due to timestamps, it won't work unless you follow up with another command chopping off the filename that follows the md5 checksum. If I were more proficient with sed or bash scripts, I could probably strip that name off easy but alas, I am not. 2) Same as your reason. :) – R Schultz Nov 17 '14 at 23:32
  • That makes a lot of sense. Your first point is very reasonable and at least, despite suffering from the second, you still managed to produce something that is perfectly correct and not the nonsense I was spouting before you fixed it. Fair enough indeed. – terdon Nov 18 '14 at 0:29
3

The latter. When you run ls file | md5sum, you are getting the md5sum of the string file\n and not of the contents of the file.

As a general rule, you never pass a file with ls file | command, there are almost no cases where that will do what you want. If you want to give a file name to a command and expect it to do something with that file, you give it as an argument:

command file

So, in the case of md5sum, you should run

$ md5sum hostname1-config.uac
  • Oh, because I wanted to do MD5 comparison. Let me format my question clearer. :) – Win.T Nov 17 '14 at 2:58
  • Thanks Terdon, you're right. It works perfectly after I removed all the 'ls' – Win.T Nov 17 '14 at 3:27
  • 2
    While I agree that the correct way is to just give the file's name as an argument, the reason the other way is wrong is incorrect. When you type ls file | md5sum, you are taking the md5sum of the filename as opposed to the file. The filename has no effect on the result of md5sum when entered as you indicated or via an alternate method cat filename | md5sum – R Schultz Nov 17 '14 at 3:37
  • Thank you R Schultz & Terdon! The correct comparison worked using cat filename | md5sum -c md5.tmp instead of 'ls' – Win.T Nov 17 '14 at 4:11
  • @R Schultz , while using the command cat filename| md5sum -c /tmp/Config/md5.tmp does work on the command line, but it does not work in the script. Can you help? Thank you! It returned me a result like this: - hostname1-config.uac: FAILED open or read – Win.T Nov 17 '14 at 4:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.