Implemented --timeout with testsuite. Updated man page for release.

This commit is contained in:
Ole Tange 2011-08-22 01:01:57 +02:00
parent 11ff97cd2e
commit 38b1fe9a41
11 changed files with 247 additions and 81 deletions

20
NEWS
View file

@ -1,3 +1,23 @@
20110822
* --timeout implemented so that slow commands can be killed
* CPU detection improved for Mac OSX. Thanks to Wayne E. Seguin.
* Example of a parallel webcrawler in the man page.
* Backup up PostgreSQL with GNU Parallel. Thanks to Stephane Wirtel.
http://wirtel.be/2011/07/15/rsync_parallel/
* Blog post in Japanese.
http://dminor11th.blogspot.com/2011/08/gnu-parallel.html
* Blog post about optimizing JPEGs. Thanks to Thomas Jost.
http://schnouki.net/2011/07/22/optimizing-jpeg-pictures/
* Bug fixes and man page updates.
20110722
* niceload: --hard will suspend a program if a limit is reached - as

View file

@ -1,4 +1,4 @@
AC_INIT([parallel], [20110722], [bug-parallel@gnu.org])
AC_INIT([parallel], [20110822], [bug-parallel@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([

View file

@ -4,9 +4,10 @@
Update documentation:
Modified => alpha
Unmodified alpha since last version => beta
git blame
Unmodified beta since last version => production
Unmodified alpha since last version => beta
Modified => alpha
== Update version ==
@ -188,7 +189,7 @@ official distributions.
Ubuntu people: Log into LaunchPad and on
https://bugs.launchpad.net/ubuntu/+bug/740630 click 'This bug affect
me too'.
me too'. (The link will only appear when you are logged in)
Debian people: This is the (2 years old) bug to push:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=518696
@ -205,7 +206,7 @@ that depend on moreutils-parallel will be aware of it.
New in this release:
(( timeout ))
* --timeout implemented so that slow commands can be killed
* CPU detection improved for Mac OSX. Thanks to Wayne E. Seguin.

View file

@ -24,7 +24,7 @@
use strict;
use Getopt::Long;
$Global::progname="niceload";
$Global::version = 20110722;
$Global::version = 20110822;
Getopt::Long::Configure("bundling","require_order");
get_options_from_array(\@ARGV) || die_usage();
if($::opt_version) {

View file

@ -30,25 +30,25 @@ run 1 second, suspend (3.00-1.00) seconds, run 1 second, suspend
=over 9
=item B<-f> I<FACTOR> (alpha testing)
=item B<-f> I<FACTOR> (beta testing)
=item B<--factor> I<FACTOR> (alpha testing)
=item B<--factor> I<FACTOR> (beta testing)
Suspend time factor. Dynamically set B<-s> as amount over limit *
factor. Default is 1.
=item B<-H> (alpha testing)
=item B<-H> (beta testing)
=item B<--hard> (alpha testing)
=item B<--hard> (beta testing)
Hard limit. B<--hard> will suspend the process until the system is
under the limits. The default is B<--soft>.
=item B<--io> I<iolimit> (alpha testing)
=item B<--io> I<iolimit> (beta testing)
=item B<-I> I<iolimit> (alpha testing)
=item B<-I> I<iolimit> (beta testing)
Limit for I/O. The amount of disk I/O will be computed as a value 0 -
10, where 0 is no I/O and 10 is at least one disk is 100% satuated.
@ -56,18 +56,18 @@ Limit for I/O. The amount of disk I/O will be computed as a value 0 -
B<--io> will set both B<--start-io> and B<run-io>.
=item B<--load> I<loadlimit> (alpha testing)
=item B<--load> I<loadlimit> (beta testing)
=item B<-L> I<loadlimit> (alpha testing)
=item B<-L> I<loadlimit> (beta testing)
Limit for load average.
B<--load> will set both B<--start-load> and B<run-load>.
=item B<--mem> I<memlimit> (alpha testing)
=item B<--mem> I<memlimit> (beta testing)
=item B<-M> I<memlimit> (alpha testing)
=item B<-M> I<memlimit> (beta testing)
Limit for free memory. This is the amount of bytes available as free
+ cache. This limit is treated opposite other limits: If the system
@ -81,9 +81,9 @@ respectively.
B<--mem> will set both B<--start-mem> and B<run-mem>.
=item B<--noswap> (alpha testing)
=item B<--noswap> (beta testing)
=item B<-N> (alpha testing)
=item B<-N> (beta testing)
No swapping. If the system is swapping both in and out it is a good
indication that the system is memory stressed.
@ -93,88 +93,88 @@ B<--noswap> is over limit if the system is swapping both in and out.
B<--noswap> will set both B<--start-noswap> and B<run-noswap>.
=item B<-n> I<niceness> (alpha testing)
=item B<-n> I<niceness> (beta testing)
=item B<--nice> I<niceness> (alpha testing)
=item B<--nice> I<niceness> (beta testing)
Sets niceness. See B<nice>(1).
=item B<-p> I<PID> (alpha testing)
=item B<-p> I<PID> (beta testing)
=item B<--pid> I<PID> (alpha testing)
=item B<--pid> I<PID> (beta testing)
Process ID of process to suspend.
=item B<--quote> (alpha testing)
=item B<--quote> (beta testing)
=item B<-q> (alpha testing)
=item B<-q> (beta testing)
Quote the command line. Useful if the command contains chars like *,
$, >, and " that should not be interpreted by the shell.
=item B<--run-io> I<iolimit> (alpha testing)
=item B<--run-io> I<iolimit> (beta testing)
=item B<--ri> I<iolimit> (alpha testing)
=item B<--ri> I<iolimit> (beta testing)
=item B<--run-load> I<loadlimit> (alpha testing)
=item B<--run-load> I<loadlimit> (beta testing)
=item B<--rl> I<loadlimit> (alpha testing)
=item B<--rl> I<loadlimit> (beta testing)
=item B<--run-mem> I<memlimit> (alpha testing)
=item B<--run-mem> I<memlimit> (beta testing)
=item B<--rm> I<memlimit> (alpha testing)
=item B<--rm> I<memlimit> (beta testing)
Run limit. The running program will be slowed down if the system is
above the limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>.
=item B<--start-io> I<iolimit> (alpha testing)
=item B<--start-io> I<iolimit> (beta testing)
=item B<--si> I<iolimit> (alpha testing)
=item B<--si> I<iolimit> (beta testing)
=item B<--start-load> I<loadlimit> (alpha testing)
=item B<--start-load> I<loadlimit> (beta testing)
=item B<--sl> I<loadlimit> (alpha testing)
=item B<--sl> I<loadlimit> (beta testing)
=item B<--start-mem> I<memlimit> (alpha testing)
=item B<--start-mem> I<memlimit> (beta testing)
=item B<--sm> I<memlimit> (alpha testing)
=item B<--sm> I<memlimit> (beta testing)
Start limit. The program will not start until the system is below the
limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>.
=item B<--soft> (alpha testing)
=item B<--soft> (beta testing)
=item B<-S> (alpha testing)
=item B<-S> (beta testing)
Soft limit. B<niceload> will suspend a process for a while and then
let it run for a second thus only slowing down a process while the
system is over one of the given limits. This is the default.
=item B<--suspend> I<SEC> (alpha testing)
=item B<--suspend> I<SEC> (beta testing)
=item B<-s> I<SEC> (alpha testing)
=item B<-s> I<SEC> (beta testing)
Suspend time. Suspend the command this many seconds when the max load
average is reached.
=item B<--recheck> I<SEC> (alpha testing)
=item B<--recheck> I<SEC> (beta testing)
=item B<-t> I<SEC> (alpha testing)
=item B<-t> I<SEC> (beta testing)
Recheck load time. Sleep SEC seconds before checking load
again. Default is 1 second.
=item B<--verbose> (alpha testing)
=item B<--verbose> (beta testing)
=item B<-v> (alpha testing)
=item B<-v> (beta testing)
Verbose. Print some extra output on what is happening. Use B<-v> until
you know what your are doing.

View file

@ -389,6 +389,7 @@ sub options_hash {
"number-of-cores" => \$::opt_number_of_cores,
"use-cpus-instead-of-cores" => \$::opt_use_cpus_instead_of_cores,
"nice=i" => \$::opt_nice,
"timeout=i" => \$::opt_timeout,
"onall" => \$::opt_onall,
"nonall" => \$::opt_nonall,
"sshlogin|S=s" => \@::opt_sshlogin,
@ -482,7 +483,7 @@ sub get_options_from_array {
sub parse_options {
# Returns: N/A
# Defaults:
$Global::version = 20110819;
$Global::version = 20110822;
$Global::progname = 'parallel';
$Global::infinity = 2**31;
$Global::debug = 0;
@ -538,6 +539,7 @@ sub parse_options {
}
if(defined $::opt_E) { $Global::end_of_file_string = $::opt_E; }
if(defined $::opt_n) { $Global::max_number_of_args = $::opt_n; }
if(defined $::opt_timeout) { $Global::timeoutq = TimeoutQueue->new($::opt_timeout); }
if(defined $::opt_tmpdir) { $ENV{'TMPDIR'} = $::opt_tmpdir; }
if(defined $::opt_help) { die_usage(); }
if(defined $::opt_colsep) { $Global::trim = 'lr'; }
@ -1579,6 +1581,20 @@ sub reaper {
return $children_reaped;
}
sub timeout {
# SIGALRM was received. Check if there was a timeout
# @Global::timeout is sorted by timeout
while (@Global::timeouts) {
my $t = $Global::timeouts[0];
if($t->timed_out()) {
$t->kill();
shift @Global::timeouts;
} else {
# Because they are sorted by timeout
last;
}
}
}
sub __USAGE__ {}
sub wait_and_exit {
@ -1735,6 +1751,10 @@ sub usleep {
my $secs = shift;
::debug("Sleeping ",$secs," millisecs\n");
select(undef, undef, undef, $secs/1000);
if($::opt_timeout) {
::debug(my_dump($Global::timeoutq));
$Global::timeoutq->process_timeouts();
}
}
sub multiply_binary_prefix {
@ -2758,6 +2778,8 @@ sub new {
'sshlogin_wrap' => undef,
'exitstatus' => undef,
'exitsignal' => undef,
# Timestamp for timeout if any
'timeout' => undef,
}, ref($class) || $class;
}
@ -2893,6 +2915,38 @@ sub set_endtime {
}
sub set_timeout {
my $self = shift;
my $delta_time = shift;
$self->{'timeout'} = time + $delta_time;
}
sub timeout {
my $self = shift;
return $self->{'timeout'};
}
sub timedout {
my $self = shift;
return time > $self->{'timeout'};
}
sub kill {
# kill the jobs
my $self = shift;
my $pid = $self->pid();
for my $signal ("TERM", "TERM", "KILL") {
# Send two TERMs to give time to clean up
if(kill 0, $pid) {
# The job still running
kill $signal, $pid;
if($signal eq "TERM") { ::usleep(200); }
} else {
# The job is already finished
last;
}
}
}
sub failed {
# return number of times failed for this $sshlogin
my $self = shift;
@ -3289,6 +3343,11 @@ sub start {
}
$job->set_pid($pid);
$job->set_starttime();
if($::opt_timeout) {
# Timeout must be set before inserting into queue
$job->set_timeout($::opt_timeout);
$Global::timeoutq->insert($job);
}
return $job;
}
@ -4213,7 +4272,8 @@ sub new {
my $fhs = shift;
for my $fh (@$fhs) {
if(-t $fh) {
print STDERR "$Global::progname: Input is tty. ".
print STDERR "$Global::progname: Input is read from the terminal. ".
"Only experts do this on purpose. ".
"Press CTRL-D to exit.\n";
}
}
@ -4495,6 +4555,60 @@ sub trim_of {
}
package TimeoutQueue;
sub new {
my $class = shift;
my $delta_time = shift;
return bless {
'queue' => [],
'delta_time' => $delta_time,
}, ref($class) || $class;
}
sub process_timeouts {
# Check if there was a timeout
my $self = shift;
# @Global::timeout is sorted by timeout
while (@{$self->{'queue'}}) {
my $job = $self->{'queue'}[0];
if($job->timedout()) {
# Need to shift off queue before kill
# because kill calls usleep -> process_timeouts
shift @{$self->{'queue'}};
$job->kill();
} else {
# Because they are sorted by timeout
last;
}
}
}
sub insert {
my $self = shift;
my $in = shift;
my $lower = 0;
my $upper = $#{$self->{'queue'}};
my $looking = int(($lower + $upper)/2);
my $in_time = $in->timeout();
# Find the position between $lower and $upper
while($lower < $upper) {
if($self->{'queue'}[$looking]->timeout() < $in_time) {
# Upper half
$lower = $looking+1;
} else {
# Lower half
$upper = $looking;
}
$looking = int(($lower + $upper)/2);
}
# splice at position $looking
splice @{$self->{'queue'}}, $looking, 0, $in;
}
package Semaphore;
# This package provides a counting semaphore
@ -4535,6 +4649,7 @@ sub new {
sub acquire {
my $self = shift;
my $sleep = 1; # 1 ms
my $start_time = time;
while(1) {
$self->atomic_link_if_count_less_than() and last;
::debug("Remove dead locks");
@ -4558,7 +4673,17 @@ sub acquire {
$sleep = ($sleep < 1000) ? ($sleep * 1.1) : ($sleep);
# Random to avoid every sleeping job waking up at the same time
::usleep(rand()*$sleep);
# TODO if timeout: last
if(defined($::opt_timeout) and
$start_time + $::opt_timeout > time) {
# Acquire the lock anyway
if(not -e $self->{'idfile'}) {
open (A, ">", $self->{'idfile'}) or
::die_bug("write_idfile: $self->{'idfile'}");
close A;
}
link $self->{'idfile'}, $self->{'pidfile'};
last;
}
}
::debug("acquired $self->{'pid'}\n");
}

View file

@ -73,7 +73,7 @@ alias or a function will not work (see why
http://www.perlmonks.org/index.pl?node_id=484296).
=item B<{}> (alpha testing)
=item B<{}> (beta testing)
Input line. This replacement string will be replaced by a full line
read from the input source. The input source is normally stdin
@ -86,7 +86,7 @@ If the command line contains no replacement strings then B<{}> will be
appended to the command line.
=item B<{.}> (alpha testing)
=item B<{.}> (beta testing)
Input line without extension. This replacement string will be replaced
by the input with the extension removed. If the input line contains
@ -102,7 +102,7 @@ The replacement string B<{.}> can be changed with B<-U>.
To understand replacement strings see B<{}>.
=item B<{/}> (alpha testing)
=item B<{/}> (beta testing)
Basename of input line. This replacement string will be replaced by
the input with the directory part removed.
@ -113,7 +113,7 @@ B<--basenamereplace>.
To understand replacement strings see B<{}>.
=item B<{//}> (alpha testing)
=item B<{//}> (beta testing)
Dirname of input line. This replacement string will be replaced by the
dir of the input line. See B<dirname>(1).
@ -124,7 +124,7 @@ B<--dirnamereplace>.
To understand replacement strings see B<{}>.
=item B<{/.}> (alpha testing)
=item B<{/.}> (beta testing)
Basename of input line without extension. This replacement string will
be replaced by the input with the directory and extension part
@ -136,7 +136,7 @@ B<--basenameextensionreplace>.
To understand replacement strings see B<{}>.
=item B<{#}> (alpha testing)
=item B<{#}> (beta testing)
Sequence number of the job to run. This replacement string will be
replaced by the sequence number of the job being run. It contains the
@ -147,7 +147,7 @@ The replacement string B<{#}> can be changed with B<--seqreplace>.
To understand replacement strings see B<{}>.
=item B<{>I<n>B<}> (alpha testing)
=item B<{>I<n>B<}> (beta testing)
Argument from input source I<n> or the I<n>'th argument. This
positional replacement string will be replaced by the input from input
@ -157,7 +157,7 @@ argument (when used with B<-N>).
To understand replacement strings see B<{}>.
=item B<{>I<n>.B<}> (alpha testing)
=item B<{>I<n>.B<}> (beta testing)
Argument from input source I<n> or the I<n>'th argument without
extension. It is a combination of B<{>I<n>B<}> and B<{.}>.
@ -170,7 +170,7 @@ extension removed.
To understand positional replacement strings see B<{>I<n>B<}>.
=item B<{>I<n>/B<}> (alpha testing)
=item B<{>I<n>/B<}> (beta testing)
Basename of argument from input source I<n> or the I<n>'th argument.
It is a combination of B<{>I<n>B<}> and B<{/}>.
@ -183,7 +183,7 @@ directory (if any) removed.
To understand positional replacement strings see B<{>I<n>B<}>.
=item B<{>I<n>/.B<}> (alpha testing)
=item B<{>I<n>/.B<}> (beta testing)
Basename of argument from input source I<n> or the I<n>'th argument
without extension. It is a combination of B<{>I<n>B<}>, B<{/}>, and
@ -197,7 +197,7 @@ directory (if any) and extension removed.
To understand positional replacement strings see B<{>I<n>B<}>.
=item B<:::> I<arguments> (beta testing)
=item B<:::> I<arguments>
Use arguments from the command line as input source instead of stdin
(standard input). Unlike other options for GNU B<parallel> B<:::> is
@ -233,7 +233,7 @@ B<:::> and B<::::> can be mixed. So these are equivalent:
seq 4 5 | parallel echo {1} {2} {3} :::: <(seq 6 7) - ::: 1 2 3
=item B<::::> I<argfiles> (beta testing)
=item B<::::> I<argfiles>
Another way to write B<-a> I<argfile1> B<-a> I<argfile2> ...
@ -393,9 +393,9 @@ as \n, or an octal or hexadecimal escape code. Octal and
hexadecimal escape codes are understood as for the printf command.
Multibyte characters are not supported.
=item B<--dirnamereplace> I<replace-str> (beta testing)
=item B<--dirnamereplace> I<replace-str>
=item B<--dnr> I<replace-str> (beta testing)
=item B<--dnr> I<replace-str>
Use the replacement string I<replace-str> instead of B<{//}> for
dirname of input line.
@ -427,7 +427,7 @@ If I<eof-str> is omitted, there is no end of file string. If neither
B<-E> nor B<-e> is used, no end of file string is used.
=item B<--eta> (beta testing)
=item B<--eta>
Show the estimated number of seconds before finishing. This forces GNU
B<parallel> to read all jobs before starting to find the number of
@ -638,7 +638,7 @@ B<-l 0> is an alias for B<-l 1>.
Implies B<-X> unless B<-m> is set.
=item B<--load> I<max-load> (beta testing)
=item B<--load> I<max-load> (alpha testing)
Do not start new jobs on a given computer unless the load is less than
I<max-load>. I<max-load> uses the same syntax as B<--jobs>, so I<100%>
@ -689,7 +689,7 @@ See also B<-X> for context replace. If in doubt use B<-X> as that will
most likely do what is needed.
=item B<--minversion> I<version> (beta testing)
=item B<--minversion> I<version>
Print the version GNU B<parallel> and exit. If the current version of
GNU B<parallel> is less than I<version> the exit code is
@ -699,7 +699,7 @@ This is useful for scripts that depend on features only available from
a certain version of GNU B<parallel>.
=item B<--nonall> (beta testing)
=item B<--nonall> (alpha testing)
B<--onall> with no arguments. Run the command on all computers given
with B<--sshlogin> but take no arguments. GNU B<parallel> will log
@ -710,7 +710,7 @@ This is useful for running the same command (e.g. uptime) on a list of
servers.
=item B<--onall> (beta testing)
=item B<--onall> (alpha testing)
Run all the jobs on all computers given with B<--sshlogin>. GNU
B<parallel> will log into B<--jobs> number of computers in parallel
@ -732,9 +732,9 @@ Instead of printing the output to stdout (standard output) the output
of each job is saved in a file and the filename is then printed.
=item B<--pipe> (beta testing)
=item B<--pipe>
=item B<--spreadstdin> (beta testing)
=item B<--spreadstdin>
Spread input to jobs on stdin (standard input). Read a block of data
from stdin (standard input) and give one block of data as input to one
@ -902,7 +902,7 @@ Use B<--regexp> to interpret B<--recstart> and B<--recend> as regular
expressions. This is slow, however.
=item B<--regexp> (beta testing)
=item B<--regexp>
Use B<--regexp> to interpret B<--recstart> and B<--recend> as regular
expressions. This is slow, however.
@ -1042,9 +1042,9 @@ Do not use the first line of input (used by GNU B<parallel> itself
when called with B<--shebang>).
=item B<-S> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]> (beta testing)
=item B<-S> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
=item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]> (beta testing)
=item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
Distribute jobs to remote computers. The jobs will be run on a list of
remote computers. GNU B<parallel> will determine the number of CPU
@ -1080,7 +1080,7 @@ B<--sshlogin> is often used with B<--transfer>, B<--return>,
B<--cleanup>, and B<--trc>.
=item B<--sshloginfile> I<filename> (beta testing)
=item B<--sshloginfile> I<filename>
File with sshlogins. The file consists of sshlogins on separate
lines. Empty lines and lines starting with '#' are ignored. Example:
@ -1109,7 +1109,8 @@ The sshloginfile '..' is special, it read sshlogins from
The sshloginfile '-' is special, too, it read sshlogins from stdin
(standard input).
=item B<--noswap> (beta testing)
=item B<--noswap>
Do not start new jobs on a given computer if there is both swap-in and
swap-out activity.
@ -1147,6 +1148,13 @@ different dir for the files. Setting B<--tmpdir> is equivalent to
setting $TMPDIR.
=item B<--timeout> I<sec> (alpha testing)
Time out for command. If the command runs for longer than I<sec>
seconds it will get killed with SIGTERM, followed by SIGTERM 200 ms
later, followed by SIGKILL 200 ms later.
=item B<--tollef>
Make GNU B<parallel> behave like Tollef's parallel command. To
@ -1313,7 +1321,7 @@ See also B<-m>.
Exit if the size (see the B<-s> option) is exceeded.
=item B<--xapply> (beta testing)
=item B<--xapply>
Read multiple files like B<xapply>. If multiple B<-a> are given, one
line will be read from each of the files. The arguments can be

View file

@ -536,7 +536,7 @@ $Global::Initfile && unlink $Global::Initfile;
exit ($err);
sub parse_options {
$Global::version = 20110722;
$Global::version = 20110822;
$Global::progname = 'sql';
# This must be done first as this may exec myself

View file

@ -1,22 +1,21 @@
#!/bin/bash
cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | nice parallel -j0 -k -L1
#cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | nice timeout -k 1 40 parallel -j0 -k -L1
echo '### Test of --retries - it should run 13 jobs in total';
seq 0 12 | stdout parallel --progress -kj100% --retries 1 -S 12/localhost,1/:,parallel@server2 -vq
seq 0 12 | stdout parallel --progress -kj100% --retries 1 -S 12/localhost,1/:,parallel@server2 -vq \
perl -e 'sleep 1;print "job{}\n";exit({})' |
perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}'
echo '### Test of --retries - it should run 25 jobs in total';
seq 0 12 | stdout parallel --progress -kj100% --retries 2 -S 12/localhost,1/:,parallel@server2 -vq
seq 0 12 | stdout parallel --progress -kj100% --retries 2 -S 12/localhost,1/:,parallel@server2 -vq \
perl -e 'sleep 1;print "job{}\n";exit({})' |
perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}'
echo '### Test of --retries - it should run 49 jobs in total';
seq 0 12 | stdout parallel --progress -kj100% --retries 4 -S 12/localhost,1/:,parallel@server2 -vq
seq 0 12 | stdout parallel --progress -kj100% --retries 4 -S 12/localhost,1/:,parallel@server2 -vq \
perl -e 'sleep 1;print "job{}\n";exit({})' |
perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}'
EOF
#EOF
echo '### Bug with --retries'
seq 1 8 | parallel --retries 2 --sshlogin 8/localhost,8/: -j+0 "hostname; false" | wc -l
seq 1 8 | parallel --retries 2 --sshlogin 8/localhost,8/: -j+1 "hostname; false" | wc -l

View file

@ -0,0 +1,7 @@
#!/bin/bash
# -L1 will join lines ending in ' '
cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | parallel -j10 -k -L1
echo '### Test --timeout';
parallel -j0 -k --timeout 1 echo {}\; sleep {}\; echo {} ::: 1.1 2.2 3.3 4.4
EOF

View file

@ -0,0 +1,6 @@
### Test --timeout
1.1
1.1
2.2
3.3
4.4