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

To the Brethren, I am trying to do the following shell equivalent in Perl:
$ /usr/bin/tar -cz /opt/back | /usr/bin/ssh myname@remote.host.com 'dd + of=/opt/rback/back.tar.gz'
Here is my Perl code:
my $tar = "/usr/bin/tar"; my $taropts = "-cz"; my $backupdir = "/opt/back"; my $ssh = "/usr/bin/ssh"; my $user = "myname"; my $remotehost = "remote.host.com"; my $remotedir = "/opt/rback"; my @args = ($tar, "$taropts", "$backupdir", "\|", $ssh, "$user\@$remot +ehost", "'dd of=$remotedir/back.tar.gz'"); system(@args) == 0 or die "System @args failed: $!\n";
When I execute this code snippet, all the output goes to STDOUT. How do I get this to work. Thanks!

Replies are listed 'Best First'.
Re: system and pipes
by matija (Priest) on Jan 18, 2006 at 15:24 UTC
    It is commendable that you're calling system with an array of references, because that avoids some of the shell exploits.

    However, since you intend to use shell redirection to accomplish your command, you can't do it this way.

    The easy way to do it would be:

    system("$tar $taropts $backupdir | $ssh $user\@$remotehost 'dd of=$rem +otedir/back.tar.gz'")
    The hard way would be starting tar in one process, the ssh/dd in another, and playing the IPC between them. Comparatively hard, for very little gain.

    In effect, you'd have to reimplement the shell redirects in order to do it. It's easier to just use the shell's redirects, and fortunately, Perl makes that possible.

      Thank you very much. It worked perfectly!!
Re: system and pipes
by glasswalk3r (Friar) on Jan 18, 2006 at 17:45 UTC

    Despite it works using system() function as told before, you may want to test using Perl modules that implements the functions that you want (tar and ssh) instead of making systems calls. You will have more control of what is happening and making your program more secure too.

    Alceu Rodrigues de Freitas Junior
    ---------------------------------
    "You have enemies? Good. That means you've stood up for something, sometime in your life." - Sir Winston Churchill
Re: system and pipes
by Anonymous Monk on Jan 18, 2006 at 19:55 UTC
    Why not just...

    system("/usr/bin/tar -cz /opt/back | /usr/bin/ssh myname@remote.host.com 'dd of=/opt/rback/back.tar.gz'");

Re: system and pipes
by svenXY (Deacon) on Jan 18, 2006 at 15:22 UTC
    Hi,
    just a rough guess, could it be that the second pipe (the one before the dd) is missing?
    Regards,
    svenXY
    Update: Found his typo, but no solution to his problem...
      I apologize as it was a mistake on my part. I had since corrected it :)
Re: system and pipes
by bravenmd (Sexton) on Jan 19, 2006 at 15:40 UTC
    Seems easier to just use:
    system("$tar $taropts $backupdir | $ssh $user\@$remotehost 'ddof=$remotedir/back.tar.gz'");