Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 206 lines (146 sloc) 5.182 kb
=head1 NAME
brackup - do a backup using Brackup
$ brackup [-v] --from=<source> --to=<target> [--output=my_backup.brackup] [--save-stats]
=head2 OPTIONS
=over 4
=item --from=NAME
Required. The source or root of your backup. Must match a [SOURCE:NAME]
config section in your ~/.brackup.conf (which is auto-created for you
on first run, so then you just have to go modify it). See L<Brackup::Root>
for more.
=item --to=NAME
Required. The destination or target for your backup. Must match a
[TARGET:NAME] config section in your ~/.brackup.conf. See L<Brackup::Target>
for more.
=item --output=FILE
Optional. Defaults to "source-target-YYYYMMDD.brackup". This is the
"metafile" index you'll need to do a restore.
=item --config=FILE
Specify the configuration file to use; defaults to ~/.brackup
=item --save-stats[=FILE]
Optional. Flag to indicate that stats output should be recorded to a
file. If =FILE is omitted, defaults to "source-target-YYYYMMDD.stats."
=item --verbose|-v
Show status during backup.
=item --dry-run
Don't actually store any data on the target.
=item --du-stats
Prints the size, in kB, of data underneath each directory
(recursively) which will be backed up.
=item --zenityprogress
Produces output suitable for piping into C<zenity --progress> to get a
pretty GUI progress bar while running a backup. This option is
incompatable with C<--verbose>, as both print to STDOUT.
Brackup is distributed as-is and comes without warranty of any kind,
expressed or implied. We aren't responsible for your data loss.
=head1 SEE ALSO
=head1 AUTHOR
Brad Fitzpatrick E<lt>brad@danga.comE<gt>
Copyright (c) 2006-2007 Six Apart, Ltd. All rights reserved.
This module is free software. You may use, modify, and/or redistribute this
software under the terms of same terms as perl itself.
use strict;
use warnings;
use Getopt::Long;
use Cwd;
use FindBin qw($Bin);
use lib "$Bin/lib";
use Brackup;
use Brackup::Util qw(noclobber_filename);
my ($src_name, $target_name, $backup_file, $stats_file, $opt_help);
my $opt_dryrun;
my $opt_verbose;
my $opt_du_stats;
my $opt_zenityprogress;
my $config_file = Brackup::Config->default_config_file_name;
my $arguments = join(' ', @ARGV);
usage() unless
'from=s' => \$src_name,
'to=s' => \$target_name,
'verbose' => \$opt_verbose,
'zenity-progress' => \$opt_zenityprogress,
'output=s' => \$backup_file,
'save-stats:s' => \$stats_file,
'help' => \$opt_help,
'dry-run' => \$opt_dryrun,
'du-stats' => \$opt_du_stats,
'config=s' => \$config_file,
usage() if @ARGV;
if ($opt_help) {
eval "use Pod::Usage;";
Pod::Usage::pod2usage( -verbose => 1, -exitval => 0 );
exit 0;
if ($opt_verbose && $opt_zenityprogress) {
die "Can't use --verbose and --zenity-progress at the same time";
my $config = eval { Brackup::Config->load($config_file) } or
if ($opt_du_stats && $src_name) {
my $root = eval { $config->load_root($src_name); } or
die "Bogus --from name";
exit 0;
usage() unless $src_name && $target_name;
my $cwd = getcwd();
sub usage {
my $why = shift || "";
if ($why) {
$why =~ s/\s+$//;
$why = "Error: $why\n\n";
die "${why}brackup --from=[source_name] --to=[target_name] [--output=<backup_metafile.brackup>]\nbrackup --help\n";
my $root = eval { $config->load_root($src_name); } or
my $target = eval { $config->load_target($target_name); } or
my @now = localtime();
$backup_file ||= sprintf("%s-%s-%04d%02d%02d.brackup",
$root->name, $target->name, $now[5]+1900, $now[4]+1, $now[3]);
$backup_file =~ s!^~/!$ENV{HOME}/! if $ENV{HOME};
$backup_file = "$cwd/$backup_file" unless $backup_file =~ m!^/!;
if (defined $stats_file) {
if ($stats_file eq '') {
($stats_file = $backup_file) =~ s/(\.brackup)?$/.stats/;
else {
$stats_file = "$cwd/$stats_file" unless $stats_file =~ m!^/!;
$backup_file = noclobber_filename($backup_file);
$stats_file = noclobber_filename($stats_file) if $stats_file;
my $backup = Brackup::Backup->new(
root => $root,
target => $target,
dryrun => $opt_dryrun,
verbose => $opt_verbose,
zenityprogress => $opt_zenityprogress,
if (my $stats = eval { $backup->backup($backup_file) }) {
warn "Backup complete.\n" if $opt_verbose;
$stats->set('Run Arguments:' => $arguments);
if ($opt_dryrun || $opt_verbose) {
if ($stats_file) {
exit 0;
} else {
warn "Error running backup: $@\n";
exit 1;
Jump to Line
Something went wrong with that request. Please try again.