parallel: --tmpl implemented.

This commit is contained in:
Ole Tange 2021-02-20 16:02:26 +01:00
parent f44eb31be6
commit fff769f675
9 changed files with 470 additions and 312 deletions

View file

@ -194,7 +194,7 @@ from:tange@gnu.org
to:parallel@gnu.org, bug-parallel@gnu.org
stable-bcc: Jesse Alama <jessealama@fastmail.fm>
Subject: GNU Parallel 20210222 ('AngSangSuKyi/Navalny/Håndbold/Larry King<<>>') released <<[stable]>>
Subject: GNU Parallel 20210222 ('Perseverance/AngSangSuKyi/Navalny/Håndbold/Larry King<<>>') released <<[stable]>>
GNU Parallel 20210222 ('') <<[stable]>> has been released. It is available for download at: http://ftpmirror.gnu.org/parallel/
@ -211,16 +211,13 @@ Quote of the month:
New in this release:
* --filter filter out jobs to run based on a GNU Parallel expression.
* --filter only run jobs where the filter is true. The filter can contain replacement strings and Perl code such as: '{1} < {2}+1'
* --tmpl <<>>
* --template takes a text file as a template with replacement strings. Then it replaces the replacement strings and saves it under a new filename.
* --plus implements {0%} {0..0%} dynamic replacement string for slot and {0#} {0..0#} dynamic replacement string for seq
* crnl
* New scheduling code, which makes -S alpha quality.
* --plus implements {0%} {0#} replacement string for zero padded slot and sequence.
* Warn if the first 3 values end in \r\n (DOS newline).
* Bug fixes and man page updates.

View file

@ -57,6 +57,7 @@ sub set_input_source_header($$) {
for(@$command_ref, @Global::ret_files,
@Global::transfer_files, $opt::tagstring,
$opt::workdir, $opt::results, $opt::retries,
@Global::template_contents, @Global::template_names,
@opt::filter) {
# Skip if undefined
$_ or next;
@ -1551,6 +1552,7 @@ sub options_hash() {
"transfer" => \$opt::transfer,
"cleanup" => \$opt::cleanup,
"basefile|bf=s" => \@opt::basefile,
"template|tmpl=s" => \%opt::template,
"B=s" => \$opt::retired,
"ctrlc|ctrl-c" => \$opt::retired,
"noctrlc|no-ctrlc|no-ctrl-c" => \$opt::retired,
@ -1811,6 +1813,20 @@ sub parse_options(@) {
push @Global::transfer_files, $opt::i || $opt::I || "{}";
}
push @Global::transfer_files, @opt::transfer_files;
if(%opt::template) {
while (my ($source, $template_name) = each %opt::template) {
if(open(my $tmpl, "<", $source)) {
local $/; # $/ = undef => slurp whole file
my $content = <$tmpl>;
push @Global::template_names, $template_name;
push @Global::template_contents, $content;
::debug("tmpl","Name: $template_name\n$content\n");
} else {
::error("Cannot open '$source'.");
wait_and_exit(255);
}
}
}
if(not defined $opt::recstart and
not defined $opt::recend) { $opt::recend = "\n"; }
$Global::blocksize = multiply_binary_prefix($opt::blocksize || "1M");
@ -2080,7 +2096,6 @@ sub parse_options(@) {
if($opt::sqlworker) { $Global::membuffer ||= 1; }
# The sqlmaster groups the arguments, so the should just read one
if($opt::sqlworker and not $opt::sqlmaster) { $Global::max_number_of_args = 1; }
}
sub check_invalid_option_combinations() {
@ -2155,7 +2170,7 @@ sub check_invalid_option_combinations() {
sub init_globals() {
# Defaults:
$Global::version = 20210202;
$Global::version = 20210205;
$Global::progname = 'parallel';
$::name = "GNU Parallel";
$Global::infinity = 2**31;
@ -2217,6 +2232,7 @@ sub init_globals() {
'{,([^}]+?)}' => 's/^($$1)/lc($1)/e;',
# Bash ${a,,A}
'{,,([^}]+?)}' => 's/($$1)/lc($1)/eg;',
# {slot} = $PARALLEL_JOBSLOT
'{slot}' => '1 $_="\${PARALLEL_JOBSLOT}";uq()',
# {host} = ssh host
@ -4084,7 +4100,7 @@ sub parse_sshlogin() {
::warning("--transferfile ignored as there are no remote --sshlogin.");
} elsif (@opt::return) {
::warning("--return ignored as there are no remote --sshlogin.");
} elsif (defined $opt::cleanup) {
} elsif (defined $opt::cleanup and not %opt::template) {
::warning("--cleanup ignored as there are no remote --sshlogin.");
} elsif (@opt::basefile) {
::warning("--basefile ignored as there are no remote --sshlogin.");
@ -7056,7 +7072,7 @@ sub compute_number_of_processes($) {
delete $Global::unkilled_children{$pid};
}
# Cleanup: Unget the command_lines or the @args
$Global::JobQueue->{'commandlinequeue'}->{'arg_queue'}->unget(@args);
$Global::JobQueue->{'commandlinequeue'}{'arg_queue'}->unget(@args);
@args = ();
$Global::JobQueue->unget(@jobs);
@jobs = ();
@ -8019,9 +8035,11 @@ sub new($) {
my $max_number_of_args = shift;
my $transfer_files = shift;
my $return_files = shift;
my $template_names = shift;
my $template_contents = shift;
my $commandlinequeue = CommandLineQueue->new
($commandref, $read_from, $context_replace, $max_number_of_args,
$transfer_files, $return_files);
$transfer_files, $return_files, $template_names, $template_contents);
my @unget = ();
return bless {
'unget' => \@unget,
@ -8036,7 +8054,10 @@ sub get($) {
$self->{'this_job_no'}++;
if(@{$self->{'unget'}}) {
return shift @{$self->{'unget'}};
my $job = shift @{$self->{'unget'}};
# {%} may have changed, so flush computed values
$job && $job->flush_cache();
return $job;
} else {
my $commandline = $self->{'commandlinequeue'}->get();
if(defined $commandline) {
@ -8165,6 +8186,11 @@ sub new($) {
}, ref($class) || $class;
}
sub flush_cache($) {
my $self = shift;
$self->{'commandline'}->flush_cache();
}
sub replaced($) {
my $self = shift;
$self->{'commandline'} or ::die_bug("commandline empty");
@ -9421,6 +9447,29 @@ sub sshlogin_wrap($) {
return $self->{'sshlogin_wrap'}{$command};
}
sub fill_templates($) {
# Replace replacement strings in template(s)
# Returns:
# @templates - File names of replaced templates
my $self = shift;
if(%opt::template) {
my @template_name =
map { $self->{'commandline'}->replace_placeholders([$_],0,0) }
@{$self->{'commandline'}{'template_names'}};
::debug("tmpl","Names: @template_name\n");
for(my $i = 0; $i <= $#template_name; $i++) {
open(my $fh, ">", $template_name[$i]) || die;
print $fh $self->{'commandline'}->
replace_placeholders([$self->{'commandline'}{'template_contents'}[$i]],0,0);
close $fh;
}
if($opt::cleanup) {
$self->add_rm(@template_name);
}
}
}
sub filter($) {
# Replace replacement strings in filter(s) and evaluate them
# Returns:
@ -9827,6 +9876,7 @@ sub start($) {
$ENV{'PARALLEL_JOBSLOT'} = $job->slot();
$ENV{'PARALLEL_TMP'} = ::tmpname("par");
$job->add_rm($ENV{'PARALLEL_TMP'});
$job->fill_templates();
::debug("run", $Global::total_running, " processes . Starting (",
$job->seq(), "): $command\n");
if($opt::pipe) {
@ -10730,6 +10780,8 @@ sub new($) {
my $max_number_of_args = shift; # for -N and normal (-n1)
my $transfer_files = shift;
my $return_files = shift;
my $template_names = shift;
my $template_contents = shift;
my $replacecount_ref = shift;
my $len_ref = shift;
my %replacecount = %$replacecount_ref;
@ -10751,10 +10803,22 @@ sub new($) {
'context_replace' => $context_replace,
'transfer_files' => $transfer_files,
'return_files' => $return_files,
'template_names' => $template_names,
'template_contents' => $template_contents,
'replaced' => undef,
}, ref($class) || $class;
}
sub flush_cache() {
my $self = shift;
for my $arglist (@{$self->{'arglist'}}) {
for my $arg (@$arglist) {
$arg->flush_cache();
}
}
$self->{'arg_queue'}->flush_cache();
}
sub seq($) {
my $self = shift;
return $self->{'seq'};
@ -11440,6 +11504,8 @@ sub new($) {
my $max_number_of_args = shift;
my $transfer_files = shift;
my $return_files = shift;
my $template_names = shift;
my $template_contents = shift;
my @unget = ();
my $posrpl;
my ($replacecount_ref, $len_ref);
@ -11455,6 +11521,7 @@ sub new($) {
# @command, --transferfile, --return,
# --tagstring, --workdir, --results
for(@command, @$transfer_files, @$return_files,
@$template_names, @$template_contents,
$opt::tagstring, $opt::workdir, $opt::results, $opt::retries,
@opt::filter) {
# Skip if undefined
@ -11560,7 +11627,9 @@ sub new($) {
}
# Add {} if no replacement strings in @command
($replacecount_ref, $len_ref, @command) =
replacement_counts_and_lengths($transfer_files,$return_files,@command);
replacement_counts_and_lengths($transfer_files, $return_files,
$template_names, $template_contents,
@command);
if("@command" =~ /^[^ \t\n=]*\257</) {
# Replacement string is (part of) the command (and not just
# argument or variable definition V1={})
@ -11574,7 +11643,7 @@ sub new($) {
}
return bless {
'unget' => \@unget,
('unget' => \@unget,
'command' => \@command,
'replacecount' => $replacecount_ref,
'arg_queue' => RecordQueue->new($read_from,$opt::colsep),
@ -11584,7 +11653,10 @@ sub new($) {
'size' => undef,
'transfer_files' => $transfer_files,
'return_files' => $return_files,
'template_names' => $template_names,
'template_contents' => $template_contents,
'seq' => $seq,
)
}, ref($class) || $class;
}
@ -11632,11 +11704,15 @@ sub replacement_counts_and_lengths($$@) {
# Input:
# \@transfer_files = array of filenames to transfer
# \@return_files = array of filenames to return
# \@template_names = array of names to copy to
# \@template_contents = array of contents to write
# @command = command template
# Output:
# \%replacecount, \%len, @command
my $transfer_files = shift;
my $return_files = shift;
my $template_names = shift;
my $template_contents = shift;
my @command = @_;
my (%replacecount,%len);
my $sum = 0;
@ -11666,6 +11742,7 @@ sub replacement_counts_and_lengths($$@) {
$noncontextlen += length $c;
}
for(@$transfer_files, @$return_files,
@$template_names, @$template_contents,
@opt::filter,
$opt::tagstring, $opt::workdir, $opt::results, $opt::retries) {
# Options that can contain replacement strings
@ -11725,6 +11802,8 @@ sub get($) {
$self->{'len'}, @command) =
replacement_counts_and_lengths($self->{'transfer_files'},
$self->{'return_files'},
$self->{'template_name'},
$self->{'template_contents'},
@$SQL::command_ref);
if("@command" =~ /^[^ \t\n=]*\257</) {
# Replacement string is (part of) the command (and not just
@ -11742,6 +11821,8 @@ sub get($) {
$self->{'max_number_of_args'},
$self->{'transfer_files'},
$self->{'return_files'},
$self->{'template_names'},
$self->{'template_contents'},
$self->{'replacecount'},
$self->{'len'},
);
@ -12024,6 +12105,16 @@ sub empty($) {
return $empty;
}
sub flush_cache($) {
my $self = shift;
for my $record (@{$self->{'unget'}}) {
for my $arg (@$record) {
$arg->flush_cache();
}
}
$self->{'arg_sub_queue'}->flush_cache();
}
sub arg_number($) {
my $self = shift;
return $self->{'arg_number'};
@ -12050,7 +12141,6 @@ sub get($) {
if(@{$self->{'unget'}}) {
return shift @{$self->{'unget'}};
}
my $unget_ref = $self->{'unget'};
if($self->{'arg_sub_queue'}->empty()) {
return undef;
}
@ -12063,7 +12153,7 @@ sub get($) {
::debug("run", "line='$line'\n");
if($line ne "") {
if($opt::csv) {
# Parse CSV
# Parse CSV and put it into a record
chomp $line;
if(not $Global::csv->parse($line)) {
die "CSV has unexpected format: ^$line^";
@ -12072,6 +12162,7 @@ sub get($) {
push @out_record, Arg->new($_);
}
} else {
# Split --colsep into record
for my $s (split /$opt::colsep/o, $line, -1) {
push @out_record, Arg->new($s);
}
@ -12100,6 +12191,14 @@ sub empty($) {
return $empty;
}
sub flush_cache($) {
my $self = shift;
for my $arg (@{$self->{'unget'}}) {
$arg->flush_cache();
}
$self->{'arg_sub_queue'}->flush_cache();
}
package SQLRecordQueue;
@ -12139,6 +12238,15 @@ sub empty($) {
return $empty;
}
sub flush_cache($) {
my $self = shift;
for my $record (@{$self->{'unget'}}) {
for my $arg (@$record) {
$arg->flush_cache();
}
}
}
package MultifileQueue;
@ -12189,6 +12297,15 @@ sub empty($) {
return $empty;
}
sub flush_cache($) {
my $self = shift;
for my $record (@{$self->{'unget'}}, @{$self->{'arg_matrix'}}) {
for my $arg (@$record) {
$arg->flush_cache();
}
}
}
sub link_get($) {
my $self = shift;
if(@{$self->{'unget'}}) {
@ -12197,19 +12314,20 @@ sub link_get($) {
my @record = ();
my $prepend;
my $empty = 1;
for my $fh (@{$self->{'fhs'}}) {
for my $i (0..$#{$self->{'fhs'}}) {
my $fh = $self->{'fhs'}[$i];
my $arg = read_arg_from_fh($fh);
if(defined $arg) {
# Record $arg for recycling at end of file
push @{$self->{'arg_matrix'}{$fh}}, $arg;
push @{$self->{'arg_matrix'}[$i]}, $arg;
push @record, $arg;
$empty = 0;
} else {
::debug("run", "EOA ");
# End of file: Recycle arguments
push @{$self->{'arg_matrix'}{$fh}}, shift @{$self->{'arg_matrix'}{$fh}};
push @{$self->{'arg_matrix'}[$i]}, shift @{$self->{'arg_matrix'}[$i]};
# return last @{$args->{'args'}{$fh}};
push @record, @{$self->{'arg_matrix'}{$fh}}[-1];
push @record, @{$self->{'arg_matrix'}[$i]}[-1];
}
}
if($empty) {
@ -13498,8 +13616,10 @@ sub main() {
}
$Global::JobQueue = JobQueue->new(
\@command,\@input_source_fh,$Global::ContextReplace,
$number_of_args,\@Global::transfer_files,\@Global::ret_files);
\@command, \@input_source_fh, $Global::ContextReplace,
$number_of_args, \@Global::transfer_files, \@Global::ret_files,
\@Global::template_names, \@Global::template_contents
);
if($opt::sqlmaster) {
# Create SQL table to hold joblog + output

View file

@ -868,9 +868,9 @@ See also: B<--cat>.
Only run jobs where I<filter> is true. I<filter> can contain
replacement strings and Perl code. Example:
parallel --filter '{1} < {2}' echo ::: {1..3} ::: {1..3}
parallel --filter '{1} < {2}+1' echo ::: {1..3} ::: {1..3}
Runs: 1,2 1,3 2,3
Runs: 1,1 1,2 1,3 2,2 2,3 3,3
=item B<--filter-hosts>
@ -1363,9 +1363,9 @@ mix. Compare:
See also: B<--group> B<--ungroup>
=item B<--xapply>
=item B<--xapply> (alpha testing)
=item B<--link>
=item B<--link> (alpha testing)
Link input sources. Read multiple input sources like B<xapply>. If
multiple input sources are given, one argument will be read from each
@ -2638,6 +2638,8 @@ Copy I<file> to I<repl>. All replacement strings in the contents of
I<file> will be replaced. All replacement strings in the name I<repl>
will be replaced.
With B<--cleanup> the new file will be removed when the job is done.
=item B<--tty>

View file

@ -21,7 +21,7 @@ par_crnl() {
printf "b\r\nc\nd\r\ne\r\nf\r\n" | parallel -k echo {}a
}
par_tmpl() {
par_tmpl1() {
tmp1=$(mktemp)
tmp2=$(mktemp)
cat <<'EOF' > "$tmp1"
@ -58,6 +58,26 @@ EOF
rm "$tmp1" "$tmp2"
}
par_tmpl2() {
tmp1=$(mktemp)
tmp2=$(mktemp)
cat <<'EOF' > "$tmp1"
=== Start tmpl1 ===
1: Job:{#} Slot:{%} All:{} Arg[1]:{1} Arg[-1]:{-1} Perl({}+4):{=$_+=4=}
EOF
cat <<'EOF' > "$tmp2"
2: Job:{#} Slot:{%} All:{} Arg[1]:{1} Arg[-1]:{-1} Perl({}+4):{=$_+=4=}
EOF
parallel -j2 --cleanup --tmpl $tmp1=t1.{#} --tmpl $tmp2=t2.{%} \
'cat t1.{#} t2.{%}' ::: 1 2 ::: a b
echo should give no files
ls t[12].*
parallel --cleanup --colsep , -j2 --tmpl $tmp1=t1.{#} --tmpl $tmp2=t2.{%} \
'cat t1.{#} t2.{%}' ::: 1,a 1,b 2,a 2,b
echo should give no files
ls t[12].*
}
par_resume_k() {
echo '### --resume -k'

View file

@ -7,8 +7,8 @@
par_plus_slot_replacement() {
echo '### show {slot} {0%} {0#}'
parallel -k --plus echo '{slot}=$PARALLEL_JOBSLOT={%}' ::: A B C
parallel -j15 -k --plus 'echo Seq: {000#} {00#} {0#}' ::: {1..100} | sort
parallel -j15 -k --plus 'sleep 0.0{}; echo Slot: {000%} {00%} {0%}' ::: {1..100} |
parallel -j15 -k --plus 'echo Seq: {0#} {#}' ::: {1..100} | sort
parallel -j15 -k --plus 'sleep 0.0{}; echo Slot: {0%} {%}' ::: {1..100} |
sort -u
}

View file

@ -1021,150 +1021,178 @@ par_testquote yash "#&/
par_testquote yash ()*=?'
par_testquote zsh "#&/
par_testquote zsh ()*=?'
par_tmpl 1.t1 /tmp/tmpl-1.1-111.111.t2
par_tmpl Template1
par_tmpl Xval: 1.1
par_tmpl Yval: 111.111
par_tmpl FixedValue: 9
par_tmpl Seq: 1
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 1.10
par_tmpl TenX: 11
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 1.1,111.111
par_tmpl val1,val2: 1.1,111.111
par_tmpl
par_tmpl 2.t1 /tmp/tmpl-1.1-222.222.t2
par_tmpl Template1
par_tmpl Xval: 1.1
par_tmpl Yval: 222.222
par_tmpl FixedValue: 9
par_tmpl Seq: 2
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 1.10
par_tmpl TenX: 11
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 1.1,222.222
par_tmpl val1,val2: 1.1,222.222
par_tmpl
par_tmpl 3.t1 /tmp/tmpl-1.1-333.333.t2
par_tmpl Template1
par_tmpl Xval: 1.1
par_tmpl Yval: 333.333
par_tmpl FixedValue: 9
par_tmpl Seq: 3
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 1.10
par_tmpl TenX: 11
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 1.1,333.333
par_tmpl val1,val2: 1.1,333.333
par_tmpl
par_tmpl 4.t1 /tmp/tmpl-2.22-111.111.t2
par_tmpl Template1
par_tmpl Xval: 2.22
par_tmpl Yval: 111.111
par_tmpl FixedValue: 9
par_tmpl Seq: 4
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 2.22
par_tmpl TenX: 22.2
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 2.22,111.111
par_tmpl val1,val2: 2.22,111.111
par_tmpl
par_tmpl 5.t1 /tmp/tmpl-2.22-222.222.t2
par_tmpl Template1
par_tmpl Xval: 2.22
par_tmpl Yval: 222.222
par_tmpl FixedValue: 9
par_tmpl Seq: 5
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 2.22
par_tmpl TenX: 22.2
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 2.22,222.222
par_tmpl val1,val2: 2.22,222.222
par_tmpl
par_tmpl 6.t1 /tmp/tmpl-2.22-333.333.t2
par_tmpl Template1
par_tmpl Xval: 2.22
par_tmpl Yval: 333.333
par_tmpl FixedValue: 9
par_tmpl Seq: 6
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 2.22
par_tmpl TenX: 22.2
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 2.22,333.333
par_tmpl val1,val2: 2.22,333.333
par_tmpl
par_tmpl 7.t1 /tmp/tmpl-3.333-111.111.t2
par_tmpl Template1
par_tmpl Xval: 3.333
par_tmpl Yval: 111.111
par_tmpl FixedValue: 9
par_tmpl Seq: 7
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 3.33
par_tmpl TenX: 33.33
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 3.333,111.111
par_tmpl val1,val2: 3.333,111.111
par_tmpl
par_tmpl 8.t1 /tmp/tmpl-3.333-222.222.t2
par_tmpl Template1
par_tmpl Xval: 3.333
par_tmpl Yval: 222.222
par_tmpl FixedValue: 9
par_tmpl Seq: 8
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 3.33
par_tmpl TenX: 33.33
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 3.333,222.222
par_tmpl val1,val2: 3.333,222.222
par_tmpl
par_tmpl 9.t1 /tmp/tmpl-3.333-333.333.t2
par_tmpl Template1
par_tmpl Xval: 3.333
par_tmpl Yval: 333.333
par_tmpl FixedValue: 9
par_tmpl Seq: 9
par_tmpl Slot: X
par_tmpl # x with 2 decimals
par_tmpl DecimalX: 3.33
par_tmpl TenX: 33.33
par_tmpl RandomVal: 0.RANDOM_NUMBER
par_tmpl
par_tmpl Template2
par_tmpl X,Y: 3.333,333.333
par_tmpl val1,val2: 3.333,333.333
par_tmpl
par_tmpl1 1.t1 /tmp/tmpl-1.1-111.111.t2
par_tmpl1 Template1
par_tmpl1 Xval: 1.1
par_tmpl1 Yval: 111.111
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 1
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 1.10
par_tmpl1 TenX: 11
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 1.1,111.111
par_tmpl1 val1,val2: 1.1,111.111
par_tmpl1
par_tmpl1 2.t1 /tmp/tmpl-1.1-222.222.t2
par_tmpl1 Template1
par_tmpl1 Xval: 1.1
par_tmpl1 Yval: 222.222
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 2
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 1.10
par_tmpl1 TenX: 11
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 1.1,222.222
par_tmpl1 val1,val2: 1.1,222.222
par_tmpl1
par_tmpl1 3.t1 /tmp/tmpl-1.1-333.333.t2
par_tmpl1 Template1
par_tmpl1 Xval: 1.1
par_tmpl1 Yval: 333.333
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 3
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 1.10
par_tmpl1 TenX: 11
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 1.1,333.333
par_tmpl1 val1,val2: 1.1,333.333
par_tmpl1
par_tmpl1 4.t1 /tmp/tmpl-2.22-111.111.t2
par_tmpl1 Template1
par_tmpl1 Xval: 2.22
par_tmpl1 Yval: 111.111
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 4
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 2.22
par_tmpl1 TenX: 22.2
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 2.22,111.111
par_tmpl1 val1,val2: 2.22,111.111
par_tmpl1
par_tmpl1 5.t1 /tmp/tmpl-2.22-222.222.t2
par_tmpl1 Template1
par_tmpl1 Xval: 2.22
par_tmpl1 Yval: 222.222
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 5
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 2.22
par_tmpl1 TenX: 22.2
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 2.22,222.222
par_tmpl1 val1,val2: 2.22,222.222
par_tmpl1
par_tmpl1 6.t1 /tmp/tmpl-2.22-333.333.t2
par_tmpl1 Template1
par_tmpl1 Xval: 2.22
par_tmpl1 Yval: 333.333
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 6
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 2.22
par_tmpl1 TenX: 22.2
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 2.22,333.333
par_tmpl1 val1,val2: 2.22,333.333
par_tmpl1
par_tmpl1 7.t1 /tmp/tmpl-3.333-111.111.t2
par_tmpl1 Template1
par_tmpl1 Xval: 3.333
par_tmpl1 Yval: 111.111
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 7
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 3.33
par_tmpl1 TenX: 33.33
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 3.333,111.111
par_tmpl1 val1,val2: 3.333,111.111
par_tmpl1
par_tmpl1 8.t1 /tmp/tmpl-3.333-222.222.t2
par_tmpl1 Template1
par_tmpl1 Xval: 3.333
par_tmpl1 Yval: 222.222
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 8
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 3.33
par_tmpl1 TenX: 33.33
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 3.333,222.222
par_tmpl1 val1,val2: 3.333,222.222
par_tmpl1
par_tmpl1 9.t1 /tmp/tmpl-3.333-333.333.t2
par_tmpl1 Template1
par_tmpl1 Xval: 3.333
par_tmpl1 Yval: 333.333
par_tmpl1 FixedValue: 9
par_tmpl1 Seq: 9
par_tmpl1 Slot: X
par_tmpl1 # x with 2 decimals
par_tmpl1 DecimalX: 3.33
par_tmpl1 TenX: 33.33
par_tmpl1 RandomVal: 0.RANDOM_NUMBER
par_tmpl1
par_tmpl1 Template2
par_tmpl1 X,Y: 3.333,333.333
par_tmpl1 val1,val2: 3.333,333.333
par_tmpl1
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:1 Slot:1 All:1a Arg[1]:1 Arg[-1]:a Perl(1a+4):54
par_tmpl2 2: Job:1 Slot:1 All:1a Arg[1]:1 Arg[-1]:a Perl(1a+4):54
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:2 Slot:2 All:1b Arg[1]:1 Arg[-1]:b Perl(1b+4):54
par_tmpl2 2: Job:2 Slot:2 All:1b Arg[1]:1 Arg[-1]:b Perl(1b+4):54
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:3 Slot:1 All:2a Arg[1]:2 Arg[-1]:a Perl(2a+4):64
par_tmpl2 2: Job:3 Slot:1 All:2a Arg[1]:2 Arg[-1]:a Perl(2a+4):64
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:4 Slot:2 All:2b Arg[1]:2 Arg[-1]:b Perl(2b+4):64
par_tmpl2 2: Job:4 Slot:2 All:2b Arg[1]:2 Arg[-1]:b Perl(2b+4):64
par_tmpl2 should give no files
par_tmpl2 ls: cannot access 't[12].*': No such file or directory
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:1 Slot:1 All:1a Arg[1]:1 Arg[-1]:a Perl(1a+4):54
par_tmpl2 2: Job:1 Slot:1 All:1a Arg[1]:1 Arg[-1]:a Perl(1a+4):54
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:2 Slot:2 All:1b Arg[1]:1 Arg[-1]:b Perl(1b+4):54
par_tmpl2 2: Job:2 Slot:2 All:1b Arg[1]:1 Arg[-1]:b Perl(1b+4):54
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:3 Slot:1 All:2a Arg[1]:2 Arg[-1]:a Perl(2a+4):64
par_tmpl2 2: Job:3 Slot:1 All:2a Arg[1]:2 Arg[-1]:a Perl(2a+4):64
par_tmpl2 === Start tmpl1 ===
par_tmpl2 1: Job:4 Slot:2 All:2b Arg[1]:2 Arg[-1]:b Perl(2b+4):64
par_tmpl2 2: Job:4 Slot:2 All:2b Arg[1]:2 Arg[-1]:b Perl(2b+4):64
par_tmpl2 should give no files
par_tmpl2 ls: cannot access 't[12].*': No such file or directory
par_tmux_command_not_found ### PARALLEL_TMUX not found
par_tmux_command_not_found parallel: Error: not-existing not found in $PATH.
par_total_from_joblog bug #47086: [PATCH] Initialize total_completed from joblog

View file

@ -270,10 +270,6 @@ par_open_files_blocks parallel: Warning: Try running 'parallel -j0 -N 2 --pipe p
par_open_files_blocks parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
par_open_files_blocks parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
par_open_files_blocks parallel: Warning: or increasing /proc/sys/fs/file-max
par_open_files_blocks parallel: Warning: Try running 'parallel -j0 -N 100 --pipe parallel -j0'
par_open_files_blocks parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
par_open_files_blocks parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
par_open_files_blocks parallel: Warning: or increasing /proc/sys/fs/file-max
par_open_files_blocks 1 of 21
par_open_files_blocks 2 of 21
par_open_files_blocks 3 of 21
@ -383,121 +379,121 @@ par_plus_slot_replacement ### show {slot} {0%} {0#}
par_plus_slot_replacement 1=1=1
par_plus_slot_replacement 2=2=2
par_plus_slot_replacement 3=3=3
par_plus_slot_replacement Seq: 001 01 1
par_plus_slot_replacement Seq: 002 02 2
par_plus_slot_replacement Seq: 003 03 3
par_plus_slot_replacement Seq: 004 04 4
par_plus_slot_replacement Seq: 005 05 5
par_plus_slot_replacement Seq: 006 06 6
par_plus_slot_replacement Seq: 007 07 7
par_plus_slot_replacement Seq: 008 08 8
par_plus_slot_replacement Seq: 009 09 9
par_plus_slot_replacement Seq: 010 10 10
par_plus_slot_replacement Seq: 011 11 11
par_plus_slot_replacement Seq: 012 12 12
par_plus_slot_replacement Seq: 013 13 13
par_plus_slot_replacement Seq: 014 14 14
par_plus_slot_replacement Seq: 015 15 15
par_plus_slot_replacement Seq: 016 16 16
par_plus_slot_replacement Seq: 017 17 17
par_plus_slot_replacement Seq: 018 18 18
par_plus_slot_replacement Seq: 019 19 19
par_plus_slot_replacement Seq: 020 20 20
par_plus_slot_replacement Seq: 021 21 21
par_plus_slot_replacement Seq: 022 22 22
par_plus_slot_replacement Seq: 023 23 23
par_plus_slot_replacement Seq: 024 24 24
par_plus_slot_replacement Seq: 025 25 25
par_plus_slot_replacement Seq: 026 26 26
par_plus_slot_replacement Seq: 027 27 27
par_plus_slot_replacement Seq: 028 28 28
par_plus_slot_replacement Seq: 029 29 29
par_plus_slot_replacement Seq: 030 30 30
par_plus_slot_replacement Seq: 031 31 31
par_plus_slot_replacement Seq: 032 32 32
par_plus_slot_replacement Seq: 033 33 33
par_plus_slot_replacement Seq: 034 34 34
par_plus_slot_replacement Seq: 035 35 35
par_plus_slot_replacement Seq: 036 36 36
par_plus_slot_replacement Seq: 037 37 37
par_plus_slot_replacement Seq: 038 38 38
par_plus_slot_replacement Seq: 039 39 39
par_plus_slot_replacement Seq: 040 40 40
par_plus_slot_replacement Seq: 041 41 41
par_plus_slot_replacement Seq: 042 42 42
par_plus_slot_replacement Seq: 043 43 43
par_plus_slot_replacement Seq: 044 44 44
par_plus_slot_replacement Seq: 045 45 45
par_plus_slot_replacement Seq: 046 46 46
par_plus_slot_replacement Seq: 047 47 47
par_plus_slot_replacement Seq: 048 48 48
par_plus_slot_replacement Seq: 049 49 49
par_plus_slot_replacement Seq: 050 50 50
par_plus_slot_replacement Seq: 051 51 51
par_plus_slot_replacement Seq: 052 52 52
par_plus_slot_replacement Seq: 053 53 53
par_plus_slot_replacement Seq: 054 54 54
par_plus_slot_replacement Seq: 055 55 55
par_plus_slot_replacement Seq: 056 56 56
par_plus_slot_replacement Seq: 057 57 57
par_plus_slot_replacement Seq: 058 58 58
par_plus_slot_replacement Seq: 059 59 59
par_plus_slot_replacement Seq: 060 60 60
par_plus_slot_replacement Seq: 061 61 61
par_plus_slot_replacement Seq: 062 62 62
par_plus_slot_replacement Seq: 063 63 63
par_plus_slot_replacement Seq: 064 64 64
par_plus_slot_replacement Seq: 065 65 65
par_plus_slot_replacement Seq: 066 66 66
par_plus_slot_replacement Seq: 067 67 67
par_plus_slot_replacement Seq: 068 68 68
par_plus_slot_replacement Seq: 069 69 69
par_plus_slot_replacement Seq: 070 70 70
par_plus_slot_replacement Seq: 071 71 71
par_plus_slot_replacement Seq: 072 72 72
par_plus_slot_replacement Seq: 073 73 73
par_plus_slot_replacement Seq: 074 74 74
par_plus_slot_replacement Seq: 075 75 75
par_plus_slot_replacement Seq: 076 76 76
par_plus_slot_replacement Seq: 077 77 77
par_plus_slot_replacement Seq: 078 78 78
par_plus_slot_replacement Seq: 079 79 79
par_plus_slot_replacement Seq: 080 80 80
par_plus_slot_replacement Seq: 081 81 81
par_plus_slot_replacement Seq: 082 82 82
par_plus_slot_replacement Seq: 083 83 83
par_plus_slot_replacement Seq: 084 84 84
par_plus_slot_replacement Seq: 085 85 85
par_plus_slot_replacement Seq: 086 86 86
par_plus_slot_replacement Seq: 087 87 87
par_plus_slot_replacement Seq: 088 88 88
par_plus_slot_replacement Seq: 089 89 89
par_plus_slot_replacement Seq: 090 90 90
par_plus_slot_replacement Seq: 091 91 91
par_plus_slot_replacement Seq: 092 92 92
par_plus_slot_replacement Seq: 093 93 93
par_plus_slot_replacement Seq: 094 94 94
par_plus_slot_replacement Seq: 095 95 95
par_plus_slot_replacement Seq: 096 96 96
par_plus_slot_replacement Seq: 097 97 97
par_plus_slot_replacement Seq: 098 98 98
par_plus_slot_replacement Seq: 099 99 99
par_plus_slot_replacement Seq: 100 100 100
par_plus_slot_replacement Slot: 001 01 1
par_plus_slot_replacement Slot: 002 02 2
par_plus_slot_replacement Slot: 003 03 3
par_plus_slot_replacement Slot: 004 04 4
par_plus_slot_replacement Slot: 005 05 5
par_plus_slot_replacement Slot: 006 06 6
par_plus_slot_replacement Slot: 007 07 7
par_plus_slot_replacement Slot: 008 08 8
par_plus_slot_replacement Slot: 009 09 9
par_plus_slot_replacement Slot: 010 10 10
par_plus_slot_replacement Slot: 011 11 11
par_plus_slot_replacement Slot: 012 12 12
par_plus_slot_replacement Slot: 013 13 13
par_plus_slot_replacement Slot: 014 14 14
par_plus_slot_replacement Slot: 015 15 15
par_plus_slot_replacement Seq: 001 1
par_plus_slot_replacement Seq: 002 2
par_plus_slot_replacement Seq: 003 3
par_plus_slot_replacement Seq: 004 4
par_plus_slot_replacement Seq: 005 5
par_plus_slot_replacement Seq: 006 6
par_plus_slot_replacement Seq: 007 7
par_plus_slot_replacement Seq: 008 8
par_plus_slot_replacement Seq: 009 9
par_plus_slot_replacement Seq: 010 10
par_plus_slot_replacement Seq: 011 11
par_plus_slot_replacement Seq: 012 12
par_plus_slot_replacement Seq: 013 13
par_plus_slot_replacement Seq: 014 14
par_plus_slot_replacement Seq: 015 15
par_plus_slot_replacement Seq: 016 16
par_plus_slot_replacement Seq: 017 17
par_plus_slot_replacement Seq: 018 18
par_plus_slot_replacement Seq: 019 19
par_plus_slot_replacement Seq: 020 20
par_plus_slot_replacement Seq: 021 21
par_plus_slot_replacement Seq: 022 22
par_plus_slot_replacement Seq: 023 23
par_plus_slot_replacement Seq: 024 24
par_plus_slot_replacement Seq: 025 25
par_plus_slot_replacement Seq: 026 26
par_plus_slot_replacement Seq: 027 27
par_plus_slot_replacement Seq: 028 28
par_plus_slot_replacement Seq: 029 29
par_plus_slot_replacement Seq: 030 30
par_plus_slot_replacement Seq: 031 31
par_plus_slot_replacement Seq: 032 32
par_plus_slot_replacement Seq: 033 33
par_plus_slot_replacement Seq: 034 34
par_plus_slot_replacement Seq: 035 35
par_plus_slot_replacement Seq: 036 36
par_plus_slot_replacement Seq: 037 37
par_plus_slot_replacement Seq: 038 38
par_plus_slot_replacement Seq: 039 39
par_plus_slot_replacement Seq: 040 40
par_plus_slot_replacement Seq: 041 41
par_plus_slot_replacement Seq: 042 42
par_plus_slot_replacement Seq: 043 43
par_plus_slot_replacement Seq: 044 44
par_plus_slot_replacement Seq: 045 45
par_plus_slot_replacement Seq: 046 46
par_plus_slot_replacement Seq: 047 47
par_plus_slot_replacement Seq: 048 48
par_plus_slot_replacement Seq: 049 49
par_plus_slot_replacement Seq: 050 50
par_plus_slot_replacement Seq: 051 51
par_plus_slot_replacement Seq: 052 52
par_plus_slot_replacement Seq: 053 53
par_plus_slot_replacement Seq: 054 54
par_plus_slot_replacement Seq: 055 55
par_plus_slot_replacement Seq: 056 56
par_plus_slot_replacement Seq: 057 57
par_plus_slot_replacement Seq: 058 58
par_plus_slot_replacement Seq: 059 59
par_plus_slot_replacement Seq: 060 60
par_plus_slot_replacement Seq: 061 61
par_plus_slot_replacement Seq: 062 62
par_plus_slot_replacement Seq: 063 63
par_plus_slot_replacement Seq: 064 64
par_plus_slot_replacement Seq: 065 65
par_plus_slot_replacement Seq: 066 66
par_plus_slot_replacement Seq: 067 67
par_plus_slot_replacement Seq: 068 68
par_plus_slot_replacement Seq: 069 69
par_plus_slot_replacement Seq: 070 70
par_plus_slot_replacement Seq: 071 71
par_plus_slot_replacement Seq: 072 72
par_plus_slot_replacement Seq: 073 73
par_plus_slot_replacement Seq: 074 74
par_plus_slot_replacement Seq: 075 75
par_plus_slot_replacement Seq: 076 76
par_plus_slot_replacement Seq: 077 77
par_plus_slot_replacement Seq: 078 78
par_plus_slot_replacement Seq: 079 79
par_plus_slot_replacement Seq: 080 80
par_plus_slot_replacement Seq: 081 81
par_plus_slot_replacement Seq: 082 82
par_plus_slot_replacement Seq: 083 83
par_plus_slot_replacement Seq: 084 84
par_plus_slot_replacement Seq: 085 85
par_plus_slot_replacement Seq: 086 86
par_plus_slot_replacement Seq: 087 87
par_plus_slot_replacement Seq: 088 88
par_plus_slot_replacement Seq: 089 89
par_plus_slot_replacement Seq: 090 90
par_plus_slot_replacement Seq: 091 91
par_plus_slot_replacement Seq: 092 92
par_plus_slot_replacement Seq: 093 93
par_plus_slot_replacement Seq: 094 94
par_plus_slot_replacement Seq: 095 95
par_plus_slot_replacement Seq: 096 96
par_plus_slot_replacement Seq: 097 97
par_plus_slot_replacement Seq: 098 98
par_plus_slot_replacement Seq: 099 99
par_plus_slot_replacement Seq: 100 100
par_plus_slot_replacement Slot: 1 1
par_plus_slot_replacement Slot: 10 10
par_plus_slot_replacement Slot: 11 11
par_plus_slot_replacement Slot: 12 12
par_plus_slot_replacement Slot: 13 13
par_plus_slot_replacement Slot: 14 14
par_plus_slot_replacement Slot: 15 15
par_plus_slot_replacement Slot: 2 2
par_plus_slot_replacement Slot: 3 3
par_plus_slot_replacement Slot: 4 4
par_plus_slot_replacement Slot: 5 5
par_plus_slot_replacement Slot: 6 6
par_plus_slot_replacement Slot: 7 7
par_plus_slot_replacement Slot: 8 8
par_plus_slot_replacement Slot: 9 9
par_profiles_with_space ### bug #42902: profiles containing arguments with space
par_profiles_with_space /bin/bash=/bin/bash
par_profiles_with_space echo '/bin/bash=/bin/bash'

View file

@ -119,7 +119,7 @@ par_eta 16
par_eta ### Test of --eta with no jobs
par_eta
par_eta Computers / CPU cores / Max jobs to run
par_eta 1:local / 8 / 8
par_eta 1:local / 8 / 1
par_eta par_eta ETA: 0s Left: 0 AVG: 0.00s 0
par_exitval_signal ### Test --joblog with exitval and Test --joblog with signal -- timing dependent
par_exitval_signal exitval=128+6 OK
@ -213,7 +213,7 @@ par_progress 16
par_progress ### Test of --progress with no jobs
par_progress
par_progress Computers / CPU cores / Max jobs to run
par_progress 1:local / 8 / 8
par_progress 1:local / 8 / 1
par_progress par_progress 0
par_replacement_slashslash ### Test {//}
par_replacement_slashslash . a
@ -303,11 +303,6 @@ par_tee_too_many_args parallel: Warning: Try running 'parallel -j0 -N 251 --pipe
par_tee_too_many_args parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
par_tee_too_many_args parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
par_tee_too_many_args parallel: Warning: or increasing /proc/sys/fs/file-max
par_tee_too_many_args parallel: Warning: No more file handles.
par_tee_too_many_args parallel: Warning: Try running 'parallel -j0 -N 100 --pipe parallel -j0'
par_tee_too_many_args parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
par_tee_too_many_args parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
par_tee_too_many_args parallel: Warning: or increasing /proc/sys/fs/file-max
par_tee_too_many_args parallel: Error: --tee requires --jobs to be higher. Try --jobs 0.
par_tee_with_premature_close --tee --pipe should send all data to all commands
par_tee_with_premature_close even if a command closes stdin before reading everything

View file

@ -11,7 +11,7 @@ par_nonall_should_not_block ### bug #47608: parallel --nonall -S lo 'echo ::: '
par_nonall_should_not_block :::
par_progress_text_max_jobs_to_run ### bug #49404: "Max jobs to run" does not equal the number of jobs specified when using GNU Parallel on remote server?
par_progress_text_max_jobs_to_run should give 10 running jobs
par_progress_text_max_jobs_to_run 1:lo / 16 / 16
par_progress_text_max_jobs_to_run 1:lo / 16 / 10
par_quoting_for_onall ### bug #35427: quoting of {2} broken for --onall
par_quoting_for_onall /bin/ls
par_remote_function_nice ### functions and --nice