ImprovedSilence
ImprovedSilence

Reputation: 113

Perl - using rsync from perl script

I'm having trouble writing up a simple perl script so I can sync two folders.
My code is:

my $string= "rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/";
`$string`;

I also tried just using the line

`rsync -va /Dropbox/Music\ \(1\)/ ~/Music/Music/;`

Next I tried:

my @args=("bash", "-c","rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/");
system(@args);`

I get the same error:

sh: -c: line 0: syntax error near unexpected token `(' each time

(yeah, those spaces and parens in the originating folder are a pain, but don't yell at me, I didn't create it....)

Upvotes: 4

Views: 6926

Answers (3)

ikegami
ikegami

Reputation: 385789

Perl isn't needed here.

#!/bin/sh
rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/

Or you could add the following to ~/.bashrc then log back in:

alias music_sync='rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/'

Upvotes: 1

ikegami
ikegami

Reputation: 385789

After executing

my $string= "rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/";

you'll see that $string contains

rsync -va ~/Dropbox/Music (1)/ ~/Music/Music/

That's not the command you want to execute. \ is special in Perl double-quoted string literals (among others). To create the string

rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/

You need

$string = "rsync -va ~/Dropbox/Music\\ \\(1\\)/ ~/Music/Music/";

Alternatively, use the multi-arg form of system. Since no shell is involved, you don't have to worry about creating string literals for the shell.

my $src = $ENV{HOME}.'/Dropbox/Music (1)/';
my $dst = $ENV{HOME}.'/Music/Music/';
system('rsync', '-va', $src, $dst);

Upvotes: 1

ruakh
ruakh

Reputation: 183301

The problem is that the actual shell command you're running is

rsync -va ~/Dropbox/Music (1)/ ~/Music/Music/

because the all the backslashes are swallowed by Perl (since it, like Bash, uses backslash as a quoting/escape character). To avoid this, you need to either use single-quotes:

system 'rsync -va ~/Dropbox/Music\ \(1\)/ ~/Music/Music/';

or else re-escape your backslashes:

system "rsync -va ~/Dropbox/Music\\ \\(1\\)/ ~/Music/Music/";

Upvotes: 1

Related Questions