mirror of https://github.com/digint/btrbk
btrbk: bugfix: run_cmd: do not redirect all stderr output, as this kills progress-viewer (pv) output
parent
a1698ef4b0
commit
614438183f
|
@ -3,6 +3,7 @@ btrbk-current
|
||||||
* Bugfix: fix monthly schedule if older than 10 weeks (close: #59).
|
* Bugfix: fix monthly schedule if older than 10 weeks (close: #59).
|
||||||
* Bugfix: fix sprintf used by config option "timestamp_format long"
|
* Bugfix: fix sprintf used by config option "timestamp_format long"
|
||||||
when using perl-5.22.0 (close: #57).
|
when using perl-5.22.0 (close: #57).
|
||||||
|
* Bugfix: fix "--progress" option (close: #64).
|
||||||
* Added "clean" command (close: #61).
|
* Added "clean" command (close: #61).
|
||||||
* Added "-n, --dry-run" option.
|
* Added "-n, --dry-run" option.
|
||||||
* Added configuration options "raw_target_compress_level",
|
* Added configuration options "raw_target_compress_level",
|
||||||
|
|
54
btrbk
54
btrbk
|
@ -325,44 +325,57 @@ sub end_transaction($$)
|
||||||
|
|
||||||
sub run_cmd(@)
|
sub run_cmd(@)
|
||||||
{
|
{
|
||||||
|
# shell-based implementation.
|
||||||
|
# this needs some redirection magic for filter_stderr to work.
|
||||||
|
# NOTE: multiple filters are not supported!
|
||||||
|
|
||||||
my @commands = (ref($_[0]) eq "HASH") ? @_ : { @_ };
|
my @commands = (ref($_[0]) eq "HASH") ? @_ : { @_ };
|
||||||
|
die unless(scalar(@commands));
|
||||||
$err = "";
|
$err = "";
|
||||||
|
|
||||||
my $cmd = "";
|
|
||||||
my $name = "";
|
|
||||||
my $destructive = 0;
|
my $destructive = 0;
|
||||||
my $pipe = "";
|
|
||||||
my $catch_stderr = 0;
|
my $catch_stderr = 0;
|
||||||
my $filter_stderr = undef;
|
my $filter_stderr = undef;
|
||||||
foreach (@commands) {
|
foreach (@commands) {
|
||||||
$_->{rsh} //= [];
|
$_->{rsh} //= [];
|
||||||
$_->{cmd} = [ @{$_->{rsh}}, @{$_->{cmd}} ];
|
$_->{cmd} = [ @{$_->{rsh}}, @{$_->{cmd}} ];
|
||||||
$_->{cmd_text} = join(' ', map { s/\n/\\n/g; "'$_'" } @{$_->{cmd}}); # ugly escape of \n, do we need to escape others?
|
$_->{cmd_text} = join(' ', map { s/\n/\\n/g; "'$_'" } @{$_->{cmd}}); # ugly escape of \n, do we need to escape others?
|
||||||
$name = $_->{name} // $_->{cmd_text};
|
$catch_stderr = 1 if($_->{catch_stderr});
|
||||||
$_->{_buf} = '';
|
$filter_stderr = $_->{filter_stderr} if($_->{filter_stderr}); # NOTE: last filter wins!
|
||||||
$cmd .= $pipe . $_->{cmd_text};
|
|
||||||
$pipe = ' | ';
|
|
||||||
if($_->{catch_stderr}) {
|
|
||||||
$catch_stderr = 1;
|
|
||||||
$filter_stderr = $_->{filter_stderr};
|
|
||||||
}
|
|
||||||
$destructive = 1 unless($_->{non_destructive});
|
$destructive = 1 unless($_->{non_destructive});
|
||||||
}
|
}
|
||||||
|
my $cmd_print = join(' | ', map { $_->{cmd_text} } @commands);
|
||||||
|
|
||||||
if($dryrun && $destructive) {
|
my $cmd = $cmd_print;
|
||||||
DEBUG "### (dryrun) $cmd";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
DEBUG "### $cmd";
|
|
||||||
|
|
||||||
if($catch_stderr) {
|
if($catch_stderr) {
|
||||||
if(scalar(@commands) == 1) {
|
if(scalar(@commands) == 1) {
|
||||||
|
# no pipes, simply redirect stderr to stdout
|
||||||
$cmd .= ' 2>&1';
|
$cmd .= ' 2>&1';
|
||||||
} else {
|
}
|
||||||
$cmd = '{ ' . $cmd . ' ; } 2>&1';
|
else
|
||||||
|
{
|
||||||
|
# pipe chain is more complicated, result is something like this:
|
||||||
|
# { btrfs send <src> 2>&3 | pv | btrfs receive <dst> 2>&3 ; } 3>&1
|
||||||
|
$cmd = "{ ";
|
||||||
|
my $pipe = "";
|
||||||
|
foreach (@commands) {
|
||||||
|
$cmd .= $pipe . $_->{cmd_text};
|
||||||
|
$cmd .= ' 2>&3' if($_->{catch_stderr});
|
||||||
|
$pipe = ' | ';
|
||||||
|
}
|
||||||
|
$cmd .= ' ; } 3>&1';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# hide redirection magic from debug output
|
||||||
|
if($dryrun && $destructive) {
|
||||||
|
DEBUG "### (dryrun) $cmd_print";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
DEBUG "### $cmd_print";
|
||||||
|
|
||||||
|
# execute command and parse output
|
||||||
|
TRACE "Executing command: $cmd";
|
||||||
my $ret = "";
|
my $ret = "";
|
||||||
$ret = `$cmd`;
|
$ret = `$cmd`;
|
||||||
chomp($ret);
|
chomp($ret);
|
||||||
|
@ -375,7 +388,7 @@ sub run_cmd(@)
|
||||||
if($catch_stderr) {
|
if($catch_stderr) {
|
||||||
$_ = $ret;
|
$_ = $ret;
|
||||||
&{$filter_stderr} ($cmd) if($filter_stderr);
|
&{$filter_stderr} ($cmd) if($filter_stderr);
|
||||||
ERROR "[$cmd] $_" if($_);
|
ERROR "[$cmd_print] $_" if($_);
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
@ -1277,6 +1290,7 @@ sub btrfs_send_receive($$$$)
|
||||||
cmd => [ qw(btrfs send), @send_options, $snapshot_path ],
|
cmd => [ qw(btrfs send), @send_options, $snapshot_path ],
|
||||||
rsh => $snapshot->{RSH},
|
rsh => $snapshot->{RSH},
|
||||||
name => "btrfs send",
|
name => "btrfs send",
|
||||||
|
catch_stderr => 1, # hack for shell-based run_cmd()
|
||||||
};
|
};
|
||||||
push @cmd_pipe, {
|
push @cmd_pipe, {
|
||||||
cmd => [ '/usr/bin/pv' ],
|
cmd => [ '/usr/bin/pv' ],
|
||||||
|
|
Loading…
Reference in New Issue