parallel: --color implemented.

This commit is contained in:
Ole Tange 2022-04-30 14:28:26 +02:00
parent 57f385d54a
commit 59c20fa265
4 changed files with 59 additions and 25 deletions

View file

@ -1801,6 +1801,7 @@ sub options_completion_hash() {
"[Tag lines with a string]:str" => \$opt::tagstring),
"ctag[Color tag]:str" => \$opt::ctag,
"ctag-string|ctagstring=s[Color tagstring]:str" => \$opt::ctagstring,
"color|colour[Colorize output]" => \$opt::color,
("onall[Run all the jobs on all computers given with --sshlogin]"
=> \$opt::onall),
"nonall[--onall with no arguments]" => \$opt::nonall,
@ -2150,7 +2151,8 @@ sub parse_options(@) {
parse_replacement_string_options();
$opt::tag ||= $opt::ctag;
$opt::tagstring ||= $opt::ctagstring;
if(defined $opt::ctag or defined $opt::ctagstring) {
if(defined $opt::ctag or defined $opt::ctagstring
or defined $opt::color) {
$Global::color = 1;
}
if(defined $opt::tag and not defined $opt::tagstring) {
@ -11098,7 +11100,18 @@ sub print_linebuffer($) {
$i = ((rindex($buf,"\n")+1) || (rindex($buf,"\r")+1));
if($i) {
# One or more complete lines were found
if($opt::tag or defined $opt::tagstring) {
if($Global::color) {
# To paint a full line, we need to turn on paint
# BEFORE printing \n
# print @$halfline_ref, substr($buf,0,$i);
my $print = join("",@$halfline_ref, substr($buf,0,$i));
chomp($print);
# print color-on \n tag
my $tag = $self->tag();
# TODO fix \r
$print =~ s/([\n\r])(?=.|$)/$tag/gs;
print $out_fh $tag,$print;
} elsif($opt::tag or defined $opt::tagstring) {
# Replace ^ with $tag within the full line
if($Global::cache_replacement_eval) {
# Replace with the same value for tag
@ -11119,9 +11132,12 @@ sub print_linebuffer($) {
$i = ::max((rindex($buf,"\n")+1),
(rindex($buf,"\r")+1));
}
}
# Print the partial line (halfline) and the last half
print $out_fh @$halfline_ref, substr($buf,0,$i);
} else {
# Print the partial line (halfline) and the last half
print $out_fh @$halfline_ref, substr($buf,0,$i);
}
# Buffer in memory for SQL and CSV-output
if($Global::membuffer) {
push(@{$self->{'output'}{$fdno}},
@ -11252,7 +11268,8 @@ sub print_normal($) {
if($Global::parset and $fdno == 1) {
$outputlength += $self->print_parset($fdno,$in_fh,$out_fh);
} elsif(defined $opt::tag or defined $opt::tagstring) {
} elsif(defined $opt::tag or defined $opt::tagstring
or $Global::color) {
# Read line by line
local $/ = "\n";
my $tag = $self->tag();
@ -11260,6 +11277,7 @@ sub print_normal($) {
$outputlength += length $_;
# Tag lines with \r, too
$_ =~ s/(?<=[\r])(?=.|$)/$tag/gs;
$Global::color and chomp();
print $out_fh $tag,$_;
if($Global::membuffer) {
push @{$self->{'output'}{$fdno}}, $tag, $_;
@ -11365,6 +11383,7 @@ sub print_joblog($) {
{
my @color;
my $color_on = "";
sub tag($) {
sub init_color() {
@ -11388,22 +11407,20 @@ sub print_joblog($) {
}
my $self = shift;
if(not defined $self->{'tag'} or not $Global::cache_replacement_eval) {
if(defined $opt::tag or defined $opt::tagstring) {
if($Global::color) {
if(not @color) { init_color() }
# Choose a value based on the seq
my $col = @color[$self->seq() % ($#color+1)];
$self->{'tag'} = "\033[48;5;".$col->[0].
";38;5;".$col->[1]."m".
$color_on = "\033[48;5;".$col->[0].";38;5;".$col->[1]."m\n";
}
if(defined $opt::tag or defined $opt::tagstring) {
$self->{'tag'} =
$color_on .
($self->{'commandline'}->
replace_placeholders([$opt::tagstring],0,0)).
"\033[00m\t";
"\t";
} else {
$self->{'tag'} = $self->{'commandline'}->
replace_placeholders([$opt::tagstring],0,0)."\t";
}
} else {
$self->{'tag'} = "";
$self->{'tag'} = $color_on;
}
}
return $self->{'tag'};
@ -14509,6 +14526,10 @@ sub main() {
drain_job_queue(@command);
::debug("init", "Done draining\n");
reapers();
if($Global::color) {
print $Global::original_stderr "\033[00m\n";
print "\033[00m\n";
}
::debug("init", "Done reaping\n");
if($Global::semaphore) {
$sem->release();

View file

@ -748,6 +748,15 @@ B<--transfer>, B<--transferfile> or B<--return>.
See also: B<--basefile> B<--transfer> B<--transferfile> B<--sshlogin>
B<--return>
=item B<--color>
Colour output.
Colour the output. Each job gets its own color combination
(background+foreground).
See also: B<--ctag> B<--ctagstring>
=item B<--colsep> I<regexp>
@ -825,7 +834,7 @@ When used with B<--pipe> only pass full CSV-records.
See also: B<--pipe> B<--link> B<{>I<n>B<}> B<--colsep> B<--header>
=item B<--ctag> I<str>
=item B<--ctag> (obsolete: use B<--color> B<--tag>)
Color tag.
@ -833,14 +842,14 @@ If the values look very similar looking at the output it can be hard
to tell when a new value is used. B<--ctag> gives each value a random
color.
See also: B<--tag>
See also: B<--color> B<--tag>
=item B<--ctagstring> I<str>
=item B<--ctagstring> I<str> (obsolete: use B<--color> B<--tagstring>)
Color tagstring.
See also: B<--ctag> B<--tagstring>
See also: B<--color> B<--ctag> B<--tagstring>
=item B<--delay> I<duration>

View file

@ -3375,10 +3375,14 @@ Summary (see legend above):
B<p> is a tiny shell script. It can color output with some predefined
colors, but is otherwise quite limited.
It maxes out at 116000 jobs (probably due to limitations in Bash).
It maxes out at 116260 jobs (probably due to limitations in Bash).
=head3 EXAMPLES FROM p
Some of the examples from B<p> cannot be implemented 100% by GNU
B<parallel>: The coloring is a bit different, and GNU B<parallel>
cannot have B<--tag> for some inputs and not for others.
The coloring done by GNU B<parallel> is not exactly the same as B<p>.
1$ p -bc blue "ping 127.0.0.1" -uc red "ping 192.168.0.1" \

View file

@ -847,7 +847,7 @@ For details: see man env_parallel
export -f my_func3
parallel -vv --workdir ... --nice 17 --env _ --trc {}.out \
-S $SERVER1 my_func3 {} ::: abc-file
ssh -l parallel lo -- exec mkdir -p ./.TMPWORKDIR && rsync --protocol 30 -rlDzR -e'ssh -l parallel' ./abc-file lo:./.TMPWORKDIR;ssh -l parallel lo -- exec perl -X -e GNU_Parallel_worker,eval+pack+q/H10000000/,join+q//,@ARGV BASE64.BASE64;_EXIT_status=$?; mkdir -p ./. && rsync --protocol 30 -rlDzR -e'ssh -l parallel' --rsync-path='cd ./.TMPWORKDIR/./.; rsync' -- lo:./abc-file.out ./.;ssh -l parallel lo -- exec 'sh -c '"'"'rm -f ./.TMPWORKDIR/abc-file 2>/dev/null;rmdir ./.TMPWORKDIR/ ./.parallel/tmp/ ./.parallel/ 2>/dev/null;rm -rf ./.TMPWORKDIR;'"'";ssh -l parallel lo -- exec 'sh -c '"'"'rm -f ./.TMPWORKDIR/abc-file.out 2>/dev/null;rmdir ./.TMPWORKDIR/ ./.parallel/tmp/ ./.parallel/ 2>/dev/null;rm -rf ./.TMPWORKDIR;'"'";ssh -l parallel lo -- exec rm -rf .TMPWORKDIR;exit $_EXIT_status;
ssh -l parallel lo -- exec mkdir -p ./.TMPWORKDIR && rsync --protocol 30 -rlDzR -e'ssh -l parallel' ./abc-file lo:./.TMPWORKDIR;ssh -l parallel lo -- exec perl -X -e GNU_Parallel_worker,eval+pack+q/H10000000/,join+q//,@ARGV BASE64;_EXIT_status=$?; mkdir -p ./. && rsync --protocol 30 -rlDzR -e'ssh -l parallel' --rsync-path='cd ./.TMPWORKDIR/./.; rsync' -- lo:./abc-file.out ./.;ssh -l parallel lo -- exec 'sh -c '"'"'rm -f ./.TMPWORKDIR/abc-file 2>/dev/null;rmdir ./.TMPWORKDIR/ ./.parallel/tmp/ ./.parallel/ 2>/dev/null;rm -rf ./.TMPWORKDIR;'"'";ssh -l parallel lo -- exec 'sh -c '"'"'rm -f ./.TMPWORKDIR/abc-file.out 2>/dev/null;rmdir ./.TMPWORKDIR/ ./.parallel/tmp/ ./.parallel/ 2>/dev/null;rm -rf ./.TMPWORKDIR;'"'";ssh -l parallel lo -- exec rm -rf .TMPWORKDIR;exit $_EXIT_status;
parset myvar1,myvar2 echo ::: a b
echo $myvar1
echo $myvar2