qball has asked for the wisdom of the Perl Monks concerning the following question:

My goal is to get the md5 digest for a remote file. What is the best approach for doing so? Should I start with using Digest::MD5?
use Digest::MD5; my $host = "host"; my $remote_file = "remote_file"; my $remote_file = "/usr/bin/rexec $host -l $user $remote_file"; open(FILE, $remote_file) or die "Can't open '$remote_file': $!"; binmode(FILE); $md5 = Digest::MD5->new; while (<FILE>) { $md5->add($_); } close(FILE); print $md5->b64digest, " $remote_file\n";
The above doesn't work for me on linux. Any suggestions?

qball~"I have node idea?!"

Replies are listed 'Best First'.
Re: md5
by robartes (Priest) on Mar 21, 2003 at 19:03 UTC
    By the looks of it, you are almost there. Apart from the two identical lexical variables problem hardburn mentioned, all you need is getting the remote file:
    my $remote_file="remote_file"; my $openstring="/usr/bin/rexec $host -l $user cat $remote_file |"; # note the cat command, and the pipe at the end open FILE, $remote_file or die "Blerch: $!\n"; $md5=Digest::MD5->new(); while (<FILE>) { $md5->add($_); } close FILE; print $md5->b64digest; warn "Code is untested.";
    Of course this presumes your .rhosts or hosts.equiv files are set up correctly.

    Update: Fixed typo in code (replaced [ by { )


      Maybe if you(qball) can run cat on the other computer, you can also run md5sum or a perl script that does the summing there as Jenda suggested. If you cannot install a script there, but that site has perl and Digest::MD5, you can do something along the lines of open FILE, "/usr/bin/rexec $host -l $user perl -e 'use Digest::MD5 ... and include the code in the command line you put into the open open.

      HTH, --traveler

      robartes, your code works well. Many thanks.

      qball~"I have node idea?!"
Re: md5
by Jenda (Abbot) on Mar 21, 2003 at 18:55 UTC

    Well the best would be to create the MD5 hash on the remote computer. Are you able to install some scripts there?

    I do not know what do you intend to use this for but it reminds me of something I do. To make sure I update all pages and other objects and/or are able to quickly find the differences between two servers I run a service (daemon for the Unixers among us) that occassionaly (and when started) generates MD5 hashes of all files I am interested in and stores them in a DBM file using file paths as keys. If I want to sync two servers I just fetch the tiny DBM files and compare the MD5 hashes.

    You might want to do something similar, except maybe you will want to start MD5 indexing "manualy" via the rexec.

    Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
       -- Rick Osborne

    Edit by castaway: Closed small tag in signature

Re: md5
by hardburn (Abbot) on Mar 21, 2003 at 17:42 UTC

    You delcare $remote_file twice with my() in the same lexical scope. Take off the my() from the second decleration.

    Reinvent a rounder wheel.

    Note: All code is untested, unless otherwise stated

      Um, as the assignment operator (=) associates rightward, the OP can actually get away with this particular case. You will get a warning though:
      use strict; my $test="fleas\n"; my $test="A camel has $test"; print $test; __END__ "my" variable $test masks earlier declaration in same scope at 244947. +pl line 5. A camel has fleas


Re: md5
by dga (Hermit) on Mar 21, 2003 at 17:52 UTC

    I am not exactly what the rexec command does but I would think that you will need a | at the end of the open to capture the output of the rexec into your program. Also unless rexec is 8 bit clean and doesn't add any header/trailer information the MD5 sum will not be correct of course. Also, I am assuming the files cannot be made available by some other means (NFS etc).

    open(LS, "/bin/ls -l |"); while(<LS>) { print; }

    This code will print out the ls command output. I think you are trying to do something similar data flow wise.