0


I am trying to get the base64 md5 value of the latest file in an oracle backup directory:

 for file in "$(find /oracle/PD1/sapbackup/b*/ -newermt $date -type f)"; do openssl md5 -binary $file | base64 && echo $file >>/md5check/$date/PD1/md5local.txt; done

When I run this command I get the full md5 checksum: Y1l1t+SGpQ7Jh0GZm9R5oTrEvfcGM7NaCuYediMH2MY= But I want to get the base64 value:

# openssl md5 -binary /oracle/PD1/sapbackup/beyrnmmq/cntrlPD1.dbf | base64
Y1l1t+SGpQ7Jh0GZm9R5oQ==

How can I do this using a for loop and output the file path + md5 value to a file?
Thanks!

2 Answers2

1

Firstly, don't loop over the output of find. Instead, use find to execute your command. This ensures that filenames do not get mangled. For the same reason, you need to quote your variable expansions.

mkdir -p "/md5check/$date/PD1"

find /oracle/PD1/sapbackup/b*/ -type f -newermt "$date" -exec sh -c ' for pathname do printf "file = %s\n" "$pathname" openssl md5 -binary "$pathname" | base64 done' sh {} + >"/md5check/$date/PD1/md5local.txt"

This would find any regular file in or below any of the /oracle/PD1/sapbackup/b*/ directories that have a modification timestamp newer than $date. For these files, a short script is executed. The script prints the pathname of the file along with the base64 encoded MD5 checksum. The output of find goes to the indicated file at the end.

The redirection to the output file could obviously be done with >> inside the script, but this would mean having to open the output file for writing more than once (also, $date is not available in there).

See also:

Kusalananda
  • 333,661
0

This should do what you are asking.

I removed the -binary option because I supposed you wanted the md5 hash.

for file in "$(find /oracle/PD1/sapbackup/b*/ -newermt $date -type f)"
do 
     MD5=$(openssl md5 $file | awk '{ print $2 }')
     BASE64=$(echo $MD5 | base64)
     echo "$file : md5 => [ ${MD5} ] / base64 => [ ${BASE64} ]" >> /md5check/$date/PD1/md5local.txt
done
Val F.
  • 101
  • Thanks so much Val. When I run your script I get the following:
    `# cat /md5check/20180613/PD1/md5local.txt /oracle/PD1/sapbackup/beyrnmmq/cntrlPD1.dbf /oracle/PD1/sapbackup/beyrnmmq/BEYRNMMQ.INCR : md5 => [ 635975b7e486a50ec98741999bd479a13ac4bdf70633b35a0ae61e762307d8c6 ] / base64 => [ NjM1OTc1YjdlNDg2YTUwZWM5ODc0MTk5OWJkNDc5YTEgM2FjNGJkZjcwNjMzYjM1YTBhZTYxZTc2MjMwN2Q4YzYK ]` I can see what you are getting at though. It doesn't spit out the base64 value, but you are on the right track I believe. Any other suggestion?
    – user294040 Jun 13 '18 at 04:34
  • Try to replace BASE64=$(echo $MD5 | base64) with BASE64=$(openssl md5 -binary $file | base64) – Val F. Jun 13 '18 at 04:57
  • Thanks @Val F I got it going now - by cutting the code down like this: for file in $(find /oracle/PD1/sapbackup/b*/ -newermt $date -type f); do MD5=$(openssl md5 -binary $file) echo $MD5 | base64 >> /md5check/$date/PD1/md5local.txt done I've removed the quotation marks around the 'for' statement and now it spits out the base64 value to a file. I'll work with this because I need to now grab those md5 values into an S3api command and compare files locally with those stored in an S3 bucket. Much appreciated for your help! Cheers – user294040 Jun 13 '18 at 05:14
  • Don't loop over the output of find: https://unix.stackexchange.com/questions/321697 – Kusalananda Jun 13 '18 at 06:29