Fixed --header bug for multiline headers. +testsuite.

Allow for --timeout 200.5% (float).
--workdir . --transfer fixed.
This commit is contained in:
Ole Tange 2013-08-17 18:24:51 +02:00
parent be6fe3846f
commit 6961852117
9 changed files with 1999 additions and 34 deletions

6
README
View file

@ -30,7 +30,11 @@ The 10 seconds installation will try do to a full installation; if
that fails, a personal installation; if that fails, a minimal that fails, a personal installation; if that fails, a minimal
installation. installation.
wget -O - pi.dk/3 | sh wget -O - pi.dk/3 | bash
or:
curl pi.dk/3/ | bash
This will literally install faster than reading the rest of this This will literally install faster than reading the rest of this
document. document.

View file

@ -209,6 +209,9 @@ New in this release:
http://www.keylength.com/en/4/ the signing key was changed from http://www.keylength.com/en/4/ the signing key was changed from
1024D/ID:FFFFFFF1 to 9888R/ID:88888888. 1024D/ID:FFFFFFF1 to 9888R/ID:88888888.
* Job ad asking for GNU Parallel expertise
http://seattle.craigslist.org/est/sof/4006079352.html
* Agalma: an automated phylogenomics workflow * Agalma: an automated phylogenomics workflow
http://arxiv.org/pdf/1307.6432 http://arxiv.org/pdf/1307.6432

View file

@ -305,12 +305,13 @@ sub spreadstdin {
my $buf = ""; my $buf = "";
my $header = ""; my $header = "";
if($opt::header) { if($opt::header) {
my $non_greedy_regexp = $opt::header; if($opt::header eq ":") { $opt::header = "(.*\n)"; }
# ? , * , + , {} => ?? , *? , +? , {}? # Number = number of lines
$non_greedy_regexp =~ s/(\?|\*|\+|\})/$1\?/g; $opt::header =~ s/^(\d+)$/"(.*\n)"x$1/e;
while(read(STDIN,substr($buf,length $buf,0),$opt::blocksize)) { while(read(STDIN,substr($buf,length $buf,0),$opt::blocksize)) {
if($buf=~s/^(.*?$non_greedy_regexp)//) { if($buf=~s/^($opt::header)//) {
$header = $1; last; $header = $1;
last;
} }
} }
} }
@ -426,7 +427,6 @@ sub spreadstdin {
} }
} }
} }
# If there is anything left in the buffer write it # If there is anything left in the buffer write it
substr($buf,0,0) = ""; substr($buf,0,0) = "";
write_record_to_pipe($chunk_number++,\$header,\$buf,$recstart,$recend,length $buf); write_record_to_pipe($chunk_number++,\$header,\$buf,$recstart,$recend,length $buf);
@ -482,7 +482,7 @@ sub round_robin_write {
if($job->stdin_buffer_length() > 0) { if($job->stdin_buffer_length() > 0) {
$something_written += $job->non_block_write(); $something_written += $job->non_block_write();
} else { } else {
$job->set_stdin_buffer($block_ref,$endpos,$recstart,$recend); $job->set_stdin_buffer($header_ref,$block_ref,$endpos,$recstart,$recend);
$block_passed = 1; $block_passed = 1;
$job->set_virgin(0); $job->set_virgin(0);
$something_written += $job->non_block_write(); $something_written += $job->non_block_write();
@ -626,7 +626,7 @@ sub options_hash {
"B=s" => \$opt::retired, "B=s" => \$opt::retired,
"ctrlc|ctrl-c" => \$opt::ctrlc, "ctrlc|ctrl-c" => \$opt::ctrlc,
"noctrlc|no-ctrlc|no-ctrl-c" => \$opt::noctrlc, "noctrlc|no-ctrlc|no-ctrl-c" => \$opt::noctrlc,
"workdir|wd=s" => \$opt::workdir, "workdir|work-dir|wd=s" => \$opt::workdir,
"W=s" => \$opt::retired, "W=s" => \$opt::retired,
"tmpdir=s" => \$opt::tmpdir, "tmpdir=s" => \$opt::tmpdir,
"tempdir=s" => \$opt::tmpdir, "tempdir=s" => \$opt::tmpdir,
@ -820,8 +820,9 @@ sub parse_options {
if(defined $opt::fg) { $Global::semaphore = 1; } if(defined $opt::fg) { $Global::semaphore = 1; }
if(defined $opt::bg) { $Global::semaphore = 1; } if(defined $opt::bg) { $Global::semaphore = 1; }
if(defined $opt::wait) { $Global::semaphore = 1; } if(defined $opt::wait) { $Global::semaphore = 1; }
if(defined $opt::timeout and $opt::timeout !~ /^\d+%?$/) { if(defined $opt::timeout and $opt::timeout !~ /^\d+(\.\d+)?%?$/) {
::error("--timeout must be seconds or percentage\n"); ::error("--timeout must be seconds or percentage\n");
wait_and_exit(255);
} }
if(defined $opt::minversion) { if(defined $opt::minversion) {
print $Global::version,"\n"; print $Global::version,"\n";
@ -3739,8 +3740,8 @@ sub write {
sub set_stdin_buffer { sub set_stdin_buffer {
my $self = shift; my $self = shift;
my ($block_ref,$endpos,$recstart,$recend) = @_; my ($header_ref,$block_ref,$endpos,$recstart,$recend) = @_;
$self->{'stdin_buffer'} = substr($$block_ref,0,$endpos); $self->{'stdin_buffer'} = ($self->virgin() ? $$header_ref : "").substr($$block_ref,0,$endpos);
if($opt::remove_rec_sep) { if($opt::remove_rec_sep) {
remove_rec_sep(\$self->{'stdin_buffer'},$recstart,$recend); remove_rec_sep(\$self->{'stdin_buffer'},$recstart,$recend);
} }
@ -3786,10 +3787,11 @@ sub non_block_write {
} else { } else {
# successfully wrote everything # successfully wrote everything
my $a=""; my $a="";
$self->set_stdin_buffer(\$a,0,"",""); $self->set_stdin_buffer(\$a,\$a,"","");
$something_written = $rv; $something_written = $rv;
} }
} }
::debug("Non-block: $something_written"); ::debug("Non-block: $something_written");
return $something_written; return $something_written;
} }
@ -4231,7 +4233,7 @@ sub workdir {
my $home = $ENV{'HOME'}; my $home = $ENV{'HOME'};
eval 'use Cwd'; eval 'use Cwd';
my $cwd = cwd(); my $cwd = cwd();
$opt::workdir = $cwd; $workdir = $cwd;
if($home) { if($home) {
# If homedir exists: remove the homedir from # If homedir exists: remove the homedir from
# workdir if cwd starts with homedir # workdir if cwd starts with homedir
@ -4247,7 +4249,7 @@ sub workdir {
my ($parent_dev, $parent_ino) = (stat($parent))[0,1]; my ($parent_dev, $parent_ino) = (stat($parent))[0,1];
if($parent_dev == $home_dev and $parent_ino == $home_ino) { if($parent_dev == $home_dev and $parent_ino == $home_ino) {
# dev and ino is the same: We found the homedir. # dev and ino is the same: We found the homedir.
$opt::workdir = join("/",@dir_parts); $workdir = join("/",@dir_parts);
last; last;
} }
} }
@ -5842,12 +5844,11 @@ package TimeoutQueue;
sub new { sub new {
my $class = shift; my $class = shift;
my $delta_time = shift; my $delta_time = shift;
my ($pct,$avg_damper); my ($pct);
if($delta_time =~ /(\d+)%/) { if($delta_time =~ /(\d+(\.\d+)?)%/) {
# Timeout in percent # Timeout in percent
$pct = $1/100; $pct = $1/100;
$delta_time = 1_000_000; $delta_time = 1_000_000;
$avg_damper = (1-0.001)/0.9;
} }
return bless { return bless {
'queue' => [], 'queue' => [],

View file

@ -553,15 +553,18 @@ status will be the exit status from the failing job.
=back =back
=item B<--header> I<regexp> =item B<--header> I<regexp> (alpha testing)
Use upto regexp as header. For normal usage the matched header Use regexp as header. For normal usage the matched header (typically
(typically the first line: B<--header '\n'>) will be split using the first line: B<--header '.*\n'>) will be split using B<--colsep>
B<--colsep> (which will default to '\t') and column names can be used (which will default to '\t') and column names can be used as
as replacement variables: B<{column name}>. For B<--pipe> the matched replacement variables: B<{column name}>.
header will be prepended to each output.
B<--header :> is an alias for B<--header '\n'>. For B<--pipe> the matched header will be prepended to each output.
B<--header :> is an alias for B<--header '.*\n'>.
If I<regexp> is a number, it will match that many lines.
=item B<-I> I<replace-str> =item B<-I> I<replace-str>

View file

@ -584,16 +584,19 @@ status will be the exit status from the failing job.
@end table @end table
@item @strong{--header} @emph{regexp} @item @strong{--header} @emph{regexp} (alpha testing)
@anchor{@strong{--header} @emph{regexp}} @anchor{@strong{--header} @emph{regexp} (alpha testing)}
Use upto regexp as header. For normal usage the matched header Use regexp as header. For normal usage the matched header (typically
(typically the first line: @strong{--header '\n'}) will be split using the first line: @strong{--header '.*\n'}) will be split using @strong{--colsep}
@strong{--colsep} (which will default to '\t') and column names can be used (which will default to '\t') and column names can be used as
as replacement variables: @strong{@{column name@}}. For @strong{--pipe} the matched replacement variables: @strong{@{column name@}}.
header will be prepended to each output.
@strong{--header :} is an alias for @strong{--header '\n'}. For @strong{--pipe} the matched header will be prepended to each output.
@strong{--header :} is an alias for @strong{--header '.*\n'}.
If @emph{regexp} is a number, it will match that many lines.
@item @strong{-I} @emph{replace-str} @item @strong{-I} @emph{replace-str}
@anchor{@strong{-I} @emph{replace-str}} @anchor{@strong{-I} @emph{replace-str}}

1881
src/parallel_tutorial.html Normal file

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,18 @@ stdout /usr/bin/time -f %e parallel --delay 2 true ::: 1 2 3 | perl -ne '$_ >= 4
echo '### Exit value should not be affected if an earlier job times out' echo '### Exit value should not be affected if an earlier job times out'
parallel -j2 --timeout 1 --joblog - -k ::: "sleep 10" "exit 255" | field 7 parallel -j2 --timeout 1 --joblog - -k ::: "sleep 10" "exit 255" | field 7
echo '### --header regexp'
(echo %head1; echo %head2; seq 5) | nice parallel -kj2 --pipe -N2 --header '(%.*\n)*' echo JOB{#}\;cat
echo '### --header num'
(echo %head1; echo %head2; seq 5) | nice parallel -kj2 --pipe -N2 --header 2 echo JOB{#}\;cat
echo '### --header regexp --round-robin'
(echo %head1; echo %head2; seq 5) | nice parallel -kj2 --pipe -N2 --round --header '(%.*\n)*' echo JOB{#}\;cat
echo '### --header num --round-robin'
(echo %head1; echo %head2; seq 5) | nice parallel -kj2 --pipe -N2 --round --header 2 echo JOB{#}\;cat
EOF EOF
rm -rf tmp rm -rf tmp

View file

@ -14,3 +14,7 @@ seq 1 100 | parallel --sshlogin "/tmp/myssh1 $SSHLOGIN1, /tmp/myssh2 $SSHLOGIN2"
echo '### --filter-hosts - OK, non-such-user, connection refused, wrong host' echo '### --filter-hosts - OK, non-such-user, connection refused, wrong host'
parallel --nonall --filter-hosts -S localhost,NoUser@localhost,154.54.72.206,"ssh 5.5.5.5" hostname parallel --nonall --filter-hosts -S localhost,NoUser@localhost,154.54.72.206,"ssh 5.5.5.5" hostname
echo '### test --workdir . in $HOME'
cd && mkdir parallel-test && cd parallel-test &&
echo OK > testfile && parallel --workdir . --transfer -S $SSHLOGIN1 cat {} ::: testfile

View file

@ -52,3 +52,57 @@ OK
Exitval Exitval
-1 -1
255 255
### --header regexp
JOB1
%head1
%head2
1
2
JOB2
%head1
%head2
3
4
JOB3
%head1
%head2
5
### --header num
JOB1
%head1
%head2
1
2
JOB2
%head1
%head2
3
4
JOB3
%head1
%head2
5
### --header regexp --round-robin
JOB1
%head1
%head2
3
4
JOB2
%head1
%head2
1
2
5
### --header num --round-robin
JOB1
%head1
%head2
1
2
5
JOB2
%head1
%head2
3
4