BackupPC-users

Re: [BackupPC-users] How do I configure DumpPreUserCmd to have multiple commands

2011-08-05 11:38:34
Subject: Re: [BackupPC-users] How do I configure DumpPreUserCmd to have multiple commands
From: "Jeffrey J. Kosowsky" <backuppc AT kosowsky DOT org>
To: "General list for user discussion, questions and support" <backuppc-users AT lists.sourceforge DOT net>
Date: Fri, 05 Aug 2011 11:36:13 -0400
Holger Parplies wrote at about 15:01:45 +0200 on Friday, August 5, 2011:
 > Hi,
 > 
 > Jeffrey J. Kosowsky wrote on 2011-08-04 01:37:23 -0400 [Re: [BackupPC-users] 
 > How do I configure DumpPreUserCmd to have multiple?commands]:
 > > Rory Toma wrote at about 18:15:32 -0700 on Wednesday, August 3, 2011:
 > >  > [...]
 > >  > In my case, I want to do something like:
 > >  > 
 > >  > rsh -n <machine> <command>; rsh -n <machine> command ; ls <sharename>; 
 > >  > ls <sharename2>
 > > 
 > > As the config.pl inline documentation *clearly* states:
 > > # Note: all Cmds are executed directly without a shell, so the prog name
 > > # needs to be a full path and you can't include shell syntax like
 > > # redirection and pipes; put that in a script if you need it.
 > > 
 > > Chaining together multiple commands separated by a ";" is a *shell*
 > > feature.
 > > 
 > > So either package it all into an explicit shell command directly, e.g.,
 > >    bash -c "rsh -n <machine> <command>; rsh -n <machine> command ; \
 > >    ls <sharename>; ls <sharename2>"
 > 
 > I'm not sure that works. As you know, *quoting* is also a shell feature. Now,
 > bash just *might* reparse its command line arguments, remove quotes, and
 > recombine arguments, but I don't feel that is very likely, because whitespace
 > between arguments will have been lost and can only be replaced by single 
 > blanks
 > (which may or may not be what was previously there). Quoting is simply
 > something that needs to be done before invoking bash to get it right. 
 > However,
 > there might be a special case for the argument to -c starting with a quote.
 > 
 > So, if bash *doesn't* recombine arguments, according to the man page, only 
 > the
 > first one will be interpreted as a command ('"rsh'). This would mean that
 > there would in fact be no way to make this work without changing the BackupPC
 > code.

All I can say is that the form bash -c "code..." does work.
I use the following 'monstrosity' to query if rsyncd is running and
start cygwin rsyncd on my Windows machine if it isn't.

$Conf{RestorePreUserCmd} =
  "\$sshPath -q -x -l  $Conf{RsyncdUserName} \$hostIP bash -c '/bin/cygrunsrv 
-Q rsyncd | /bin/egrep -q \"Current State *: *Running\" || ( /usr/bin/rm -f 
/var/run/rsyncd.pid; /bin/cygrunsrv -S rsyncd ; sleep 20)'";

While the code is ugly, I did it to avoid having an extraneous shell
script hanging around that I would have to remember to always copy
over and update. The reality is I almost never use BackupPC for
restores, so I preferred doing it this way (I usually do restores
manually via BackupPC_zcat for single files if I just want the content
or via backuppc-fuse when I want the permissions and timestamps)

 > You *could*, however, use Perl code to achieve the same thing.
 > 
 >      $Conf{DumpPreUserCmd} = '&sub{ system ("...");}';
 > 
 > where "..." is your 'rsh; rsh; ls; ls' sequence (system() uses a shell if it
 > finds shell metacharacters - such as a semicolon - in the command).

As I mentioned in my recent post, your perl code *won't* work due to 2
bugs in the current BackupPC code.

First, due to inconsistent handling of strings vs. arrays in the
Lib.pm routines like cmdVarSubstitute, perl code must must be passed
as an arrayref of strings of coderefs. (the problem is that the
command converts strings to arryrefs but returns a single coderef
unmodified so that subsequent routines that expect an arrayref fail
with the error:
          Can't use string ("&{sub { blah blah blah ;}}") as an ARRAY ref while
          "strict refs" in use at /usr/share/BackupPC/bin/BackupPC_dump

So, unless the code is fixed, one would need to pass something like:
$Conf{DumpPreUserCmd} = ["&sub{ system ("...");}"];

Second, when you do pass an arrayref, you will get an error since
there is a syntax error in Lib.pm (occurs twice) where the join
command to concatenate the elements of the array into string doesn't
properly reference the array -- i.e. it references the arrayref rather
than the array itself. Specifically, the following
    $cmd = join(" ", $cmd) if ( ref($cmd) eq "ARRAY" );
needs to be changed to:
    $cmd = join(" ", @$cmd) if ( ref($cmd) eq "ARRAY" );


 > Disclaimer: both that the 'bash -c' version doesn't work and that the Perl
 > version does are untested.

Well, 'bash -c' *does* work and given the above caveats and bug fixes,
the perl code will work (I have tested it!), but you will need to
patch Lib.pm first...

 > 
 > > Or package it all together into a shell shell secret
 > 
 > That is probably meant to read "shell script" ;-). That is without doubt the
 > most simple solution (and the one recommended in the config.pl comment).

Well, I keep a lot of my shell scripts secret :P does that count?
But yes it should have read 'script'.

That being said, shell scripts are easiest to use and debug.

------------------------------------------------------------------------------
BlackBerry&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts. 
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
BackupPC-users mailing list
BackupPC-users AT lists.sourceforge DOT net
List:    https://lists.sourceforge.net/lists/listinfo/backuppc-users
Wiki:    http://backuppc.wiki.sourceforge.net
Project: http://backuppc.sourceforge.net/