Implemented --tty as the old default of assigning a tty to the first

job causes problems.
Cleanup if --workdir <> . did not work. Fixed.
This commit is contained in:
Ole Tange 2010-12-21 18:08:16 +01:00
parent ec51739620
commit a16d120711
16 changed files with 479 additions and 120 deletions

2
README
View file

@ -6,7 +6,7 @@ Please send problems and feedback to bug-parallel@gnu.org.
= Presentation of GNU Parallel =
GNU Parallel is a shell tool for executing jobs in parallel using one
or more machines. A job is typically a single command or a small
or more computers. A job is typically a single command or a small
script that has to be run for each of the lines in the input. The
typical input is a list of files, a list of hosts, a list of users, or
a list of tables.

20
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.67 for parallel 20101206.
# Generated by GNU Autoconf 2.67 for parallel 20101220.
#
# Report bugs to <bug-parallel@gnu.org>.
#
@ -551,8 +551,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='parallel'
PACKAGE_TARNAME='parallel'
PACKAGE_VERSION='20101206'
PACKAGE_STRING='parallel 20101206'
PACKAGE_VERSION='20101220'
PACKAGE_STRING='parallel 20101220'
PACKAGE_BUGREPORT='bug-parallel@gnu.org'
PACKAGE_URL=''
@ -1168,7 +1168,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures parallel 20101206 to adapt to many kinds of systems.
\`configure' configures parallel 20101220 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1234,7 +1234,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of parallel 20101206:";;
short | recursive ) echo "Configuration of parallel 20101220:";;
esac
cat <<\_ACEOF
@ -1301,7 +1301,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
parallel configure 20101206
parallel configure 20101220
generated by GNU Autoconf 2.67
Copyright (C) 2010 Free Software Foundation, Inc.
@ -1318,7 +1318,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by parallel $as_me 20101206, which was
It was created by parallel $as_me 20101220, which was
generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@
@ -2133,7 +2133,7 @@ fi
# Define the identity of the package.
PACKAGE='parallel'
VERSION='20101206'
VERSION='20101220'
cat >>confdefs.h <<_ACEOF
@ -2684,7 +2684,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by parallel $as_me 20101206, which was
This file was extended by parallel $as_me 20101220, which was
generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -2746,7 +2746,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
parallel config.status 20101206
parallel config.status 20101220
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"

View file

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

View file

@ -1,3 +1,6 @@
cleanup of transferred files in workdir fixed.
-T implemented as ssh/rsync sometimes hang due to getting a tty.
Til QUOTING:
FN="two spaces"
@ -309,7 +312,8 @@ distribute the arguments evenly if running -X.
=head1 options
One char options not used: A F G K O Q R T Z
One char options not used: A F G K O Q R T Z c f
-T terminal
=head1 sem

View file

@ -22,7 +22,7 @@ rm -fr autom4te.cache aclocal.m4 config.h config.h.in config.log Makefile.in mis
rm -rf src/Makefile.in
autoreconf --install -W gnu
./configure
make && sudo make install
make -j && sudo make install
== Testsuite ==
@ -89,9 +89,14 @@ https://savannah.gnu.org/news/approve.php?group=parallel
http://www.gnu.org/software/parallel/
http://www.gnu.org/software/parallel/man.html
http://www.gnu.org/software/parallel/sql.html
http://www.gnu.org/software/parallel/sem.html
http://www.gnu.org/software/parallel/niceload.html
pod2html src/parallel > ../parallel-web/parallel/man.html
pod2html src/parallel.pod > ../parallel-web/parallel/man.html
pod2html src/sql > ../parallel-web/parallel/sql.html
pod2html src/niceload > ../parallel-web/parallel/niceload.html
pod2html src/sem.pod > ../parallel-web/parallel/sem.html
cd ../parallel-web/parallel
cvs up
cvs ci
@ -125,11 +130,13 @@ cc:Peter Simons <simons@cryp.to>, Sandro Cazzaniga <kharec@mandriva.org>,
Andrew McFague <amcfague@wgen.net>, Steven M. Christensen <sunfreeware@gmail.com>,
Chris Howey <howeyc@gmail.com>, Fethican Coşkuner <fethicanc@gmail.com>,
Rogério Brito <rbrito@ime.usp.br>, Jonathan Palardy <jonathan.palardy@gmail.com>,
Koen Vervloesem <koen@vervloesem.eu>, R. Tyler Croy <tyler@monkeypox.org>
Koen Vervloesem <koen@vervloesem.eu>, R. Tyler Croy <tyler@monkeypox.org>,
ryoichiro.suzuki@gmail.com,kerick@shiftedbit.net,
Christian Faulhammer <fauli@gentoo.org>
Subject: GNU Parallel 20101202 released
Subject: GNU Parallel 20101222 released
GNU Parallel 20101202 has been released. It is available for
GNU Parallel 20101222 has been released. It is available for
download at: http://ftp.gnu.org/gnu/parallel/
New in this release:
@ -146,13 +153,26 @@ New in this release:
* Implemented --nice set the niceness of jobs running both locally and
remotely.
* Implemented --dry-run to print the job without running it.
* Implemented --tty as the old default of assigning a tty to the first
job causes problems.
* Review with focus on clusters. Thanks to Taylor Gillespie
http://www.unixpronews.com/unixpronews-49-20101019GNUParallelSpeedUpProcessingWithMulticoresClusters.html
* Review with focus on protein similarity.
http://kevinformatics.tumblr.com/post/2142473893/cluster-like-computing-using-gnu-parallel
* Review in Spanish.
http://gr3p.com/2010/12/gnu-parallel-acelera-tus-scripts-en-linux
* Quite a few bug fixes and man page updates.
= About GNU Parallel =
GNU Parallel is a shell tool for executing jobs in parallel using one
or more machines. A job is typically a single command or a small
or more computers. A job is typically a single command or a small
script that has to be run for each of the lines in the input. The
typical input is a list of files, a list of hosts, a list of users, a
list of URLs, or a list of tables.

View file

@ -18,21 +18,21 @@ niceload.1: niceload Makefile
pod2man --release='$(PACKAGE_VERSION)' --center='$(PACKAGE_NAME)' \
--section=1 $(srcdir)/niceload > $(srcdir)/niceload.1
parallel.html: parallel Makefile
pod2html $(srcdir)/parallel > $(srcdir)/parallel.html
rm -f $(srcdir)/pod2htm*
parallel.html: parallel Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/parallel.pod > $(srcdir)/parallel.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sem.html: sem.pod Makefile
pod2html $(srcdir)/sem.pod > $(srcdir)/sem.html
rm -f $(srcdir)/pod2htm*
sem.html: sem.pod Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/sem.pod > $(srcdir)/sem.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sql.html: sql Makefile
pod2html $(srcdir)/sql > $(srcdir)/sql.html
rm -f $(srcdir)/pod2htm*
sql.html: sql Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/sql > $(srcdir)/sql.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
niceload.html: niceload Makefile
pod2html $(srcdir)/niceload > $(srcdir)/niceload.html
rm -f $(srcdir)/pod2htm*
niceload.html: niceload Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/niceload > $(srcdir)/niceload.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sem: parallel
ln -fs parallel sem

View file

@ -463,21 +463,21 @@ niceload.1: niceload Makefile
pod2man --release='$(PACKAGE_VERSION)' --center='$(PACKAGE_NAME)' \
--section=1 $(srcdir)/niceload > $(srcdir)/niceload.1
parallel.html: parallel Makefile
pod2html $(srcdir)/parallel > $(srcdir)/parallel.html
rm -f $(srcdir)/pod2htm*
parallel.html: parallel Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/parallel.pod > $(srcdir)/parallel.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sem.html: sem.pod Makefile
pod2html $(srcdir)/sem.pod > $(srcdir)/sem.html
rm -f $(srcdir)/pod2htm*
sem.html: sem.pod Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/sem.pod > $(srcdir)/sem.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sql.html: sql Makefile
pod2html $(srcdir)/sql > $(srcdir)/sql.html
rm -f $(srcdir)/pod2htm*
sql.html: sql Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/sql > $(srcdir)/sql.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
niceload.html: niceload Makefile
pod2html $(srcdir)/niceload > $(srcdir)/niceload.html
rm -f $(srcdir)/pod2htm*
niceload.html: niceload Makefile sem
./sem --fg --id pod2html pod2html $(srcdir)/niceload > $(srcdir)/niceload.html
./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sem: parallel
ln -fs parallel sem

View file

@ -142,6 +142,7 @@ sub get_options_from_array {
"workdir|W=s" => \$::opt_workdir,
"tmpdir=s" => \$::opt_tmpdir,
"tempdir=s" => \$::opt_tmpdir,
"tty|T" => \$::opt_tty,
"halt-on-error|H=s" => \$::opt_halt_on_error,
"retries=i" => \$::opt_retries,
"dry-run|dryrun" => \$::opt_dryrun,
@ -192,7 +193,7 @@ sub get_options_from_array {
sub parse_options {
# Returns: N/A
# Defaults:
$Global::version = 20101217;
$Global::version = 20101220;
$Global::progname = 'parallel';
$Global::debug = 0;
$Global::verbose = 0;
@ -234,7 +235,9 @@ sub parse_options {
if(defined $::opt_U) { $Global::replace{'{.}'} = $::opt_U; }
if(defined $::opt_i and $::opt_i) { $Global::replace{'{}'} = $::opt_i; }
if(defined $::opt_basenamereplace) { $Global::replace{'{/}'} = $::opt_basenamereplace; }
if(defined $::opt_basenameextensionreplace) { $Global::replace{'{/.}'} = $::opt_basenameextensionreplace; }
if(defined $::opt_basenameextensionreplace) {
$Global::replace{'{/.}'} = $::opt_basenameextensionreplace;
}
if(defined $::opt_E and $::opt_E) { $Global::end_of_file_string = $::opt_E; }
if(defined $::opt_n and $::opt_n) { $Global::max_number_of_args = $::opt_n; }
if(defined $::opt_N and $::opt_N) { $Global::max_number_of_args = $::opt_N; }
@ -245,8 +248,12 @@ sub parse_options {
if(defined $::opt_arg_sep) { $Global::arg_sep = $::opt_arg_sep; }
if(defined $::opt_arg_file_sep) { $Global::arg_file_sep = $::opt_arg_file_sep; }
if(defined $::opt_number_of_cpus) { print SSHLogin::no_of_cpus(),"\n"; wait_and_exit(0); }
if(defined $::opt_number_of_cores) { print SSHLogin::no_of_cores(),"\n"; wait_and_exit(0); }
if(defined $::opt_max_line_length_allowed) { print CommandMaxLength::real_max_length(),"\n"; wait_and_exit(0); }
if(defined $::opt_number_of_cores) {
print SSHLogin::no_of_cores(),"\n"; wait_and_exit(0);
}
if(defined $::opt_max_line_length_allowed) {
print Limits::Command::real_max_length(),"\n"; wait_and_exit(0);
}
if(defined $::opt_version) { version(); wait_and_exit(0); }
if(defined $::opt_show_limits) { show_limits(); }
if(defined @::opt_sshlogin) { @Global::sshlogin = @::opt_sshlogin; }
@ -258,6 +265,16 @@ sub parse_options {
if(defined $::opt_fg) { $Global::semaphore = 1; }
if(defined $::opt_bg) { $Global::semaphore = 1; }
if(defined $::opt_wait) { $Global::semaphore = 1; }
if(defined $::opt_tty) {
# Defaults for --tty: -j1 -u
# Can be overridden with -jXXX -g
if(not defined $::opt_P) {
$::opt_P = 1;
}
if(not defined $::opt_g) {
$Global::grouped = 0;
}
}
if(defined @::opt_trc) {
push @Global::ret_files, @::opt_trc;
$::opt_transfer = 1;
@ -625,7 +642,7 @@ sub init_run_jobs {
}
}
sub login_and_host {
sub __login_and_host {
# Returns:
# login@hostname
my $sshlogin = shift;
@ -757,9 +774,9 @@ sub progress {
$status = $eta .
join(" ",map
{ sprintf("%s:%d/%d/%d%%",
$sshlogin{$_},
$sshlogin{$_},
$Global::host{$_}->jobs_running(),
($Global::host{$_}->jobs_completed()||0),
($Global::host{$_}->jobs_completed()||0),
($Global::host{$_}->jobs_running()+
($Global::host{$_}->jobs_completed()||0))*100
/ $Global::total_started) }
@ -771,9 +788,9 @@ sub progress {
$status = $eta .
join(" ",map
{ sprintf("%s:%d/%d/%d%%",
$workerno{$_},
$workerno{$_},
$Global::host{$_}->jobs_running(),
($Global::host{$_}->jobs_completed()||0),
($Global::host{$_}->jobs_completed()||0),
($Global::host{$_}->jobs_running()+
($Global::host{$_}->jobs_completed()||0))*100
/ $Global::total_started) }
@ -933,7 +950,7 @@ sub get_job_with_sshlogin {
if($::oodebug and $Global::JobQueue->empty()) {
Carp::confess("get_job_with_sshlogin should never be called if empty");
}
my ($job) = $Global::JobQueue->get();
if(not defined $job) {
# No more jobs
@ -1089,7 +1106,7 @@ sub cleanup_basefile {
}
sub __SIGNAL_HANDLING__ {}
sub list_running_jobs {
# Returns: N/A
for my $v (values %Global::running) {
@ -1369,7 +1386,7 @@ sub string {
sub jobs_running {
my $self = shift;
return ($self->{'jobs_running'} || "0");
}
@ -1383,10 +1400,10 @@ sub dec_jobs_running {
$self->{'jobs_running'}--;
}
sub set_jobs_running {
my $self = shift;
$self->{'jobs_running'} = 0;
}
#sub set_jobs_running {
# my $self = shift;
# $self->{'jobs_running'} = shift;
#}
sub set_maxlength {
my $self = shift;
@ -1786,7 +1803,7 @@ sub ncpus {
if($ncpu =~ /^[0-9]+$/) {
$self->{'ncpus'} = $ncpu;
} else {
print $Global::original_stderr
print $Global::original_stderr
("Warning: Could not figure out ",
"number of cpus on $serverlogin. Using 1\n");
$self->{'ncpus'} = 1;
@ -1794,7 +1811,7 @@ sub ncpus {
}
}
return $self->{'ncpus'};
}
}
sub no_of_cpus {
# Returns:
@ -2045,7 +2062,7 @@ sub get {
return undef;
}
}
}
}
sub unget {
my $self = shift;
@ -2083,7 +2100,7 @@ sub quote_args {
my $self = shift;
return $self->{'commandlinequeue'}->quote_args();
}
package Job;
@ -2098,8 +2115,8 @@ sub new {
'stderr' => undef,
'pid' => undef,
# hash of { SSHLogins => number of times the command failed there }
'failed' => undef,
'sshlogin' => undef,
'failed' => undef,
'sshlogin' => undef,
# The commandline wrapped with rsync and ssh
'sshlogin_wrap' => undef,
'exitstatus' => undef,
@ -2378,8 +2395,8 @@ sub sshcleanup {
join(" ",map { ::shell_quote_scalar($workdir."/".$_) } @subworkdirs);
}
my $relpath = ($file !~ m:^/:); # Is the path relative?
my $cleandir = ($relpath ? $workdir : "");
$cleancmd .= "$sshcmd $serverlogin rm -f ".::shell_quote_scalar($file.$removeworkdir).";";
my $cleandir = ($relpath ? $workdir."/" : "");
$cleancmd .= "$sshcmd $serverlogin rm -f ".::shell_quote_scalar($cleandir.$file.$removeworkdir).";";
}
return $cleancmd;
}
@ -2499,7 +2516,7 @@ sub start {
# Re-open to avoid complaining
open STDIN, "<&", $Global::original_stdin
or die "Can't dup \$Global::original_stdin: $!";
} elsif (not $Global::tty_taken and -c "/dev/tty" and
} elsif ($::opt_tty and not $Global::tty_taken and -c "/dev/tty" and
open(DEVTTY, "/dev/tty")) {
# Give /dev/tty to the command if no one else is using it
$pid = ::open3("<&DEVTTY", ">&STDOUT", ">&STDERR", $command) ||
@ -2712,7 +2729,7 @@ sub push {
push @{$self->{'arg_list'}}, $record;
#::my_dump($record);
my $arg_no = ($self->number_of_args()-1) * ($#$record+1);
for my $arg (@$record) {
$arg_no++;
if(defined $arg) {
@ -2770,7 +2787,7 @@ sub len {
# Add the length for each time
for my $replstring (keys %{$self->{'replacecount'}}) {
if(defined $self->{'len'}{$replstring}) {
$len += $self->{'len'}{$replstring} *
$len += $self->{'len'}{$replstring} *
$self->{'replacecount'}{$replstring};
}
if($Global::replace{$replstring}) {
@ -2791,7 +2808,7 @@ sub len {
sub multi_regexp {
if(not $CommandLine::multi_regexp) {
$CommandLine::multi_regexp =
$CommandLine::multi_regexp =
"(?:".
join("|",map {my $a=$_; $a =~ s/(\W)/\\$1/g; $a}
($Global::replace{"{}"},
@ -2812,7 +2829,7 @@ sub number_of_replacements {
my $sum = 0;
my $cmd = $command;
my $multi_regexp = multi_regexp();
my $replacement_regexp =
my $replacement_regexp =
"(?:".
'\{\d+/?\.?\}'. # {n}, {n.} {n/.} {n/}
'|'.
@ -2827,7 +2844,7 @@ sub number_of_replacements {
}
$sum++;
}
my $number_of_context_groups = 0;
my $no_args;
my $context;
@ -2911,11 +2928,11 @@ sub replace_placeholders {
CORE::push @used_multi, $replacementfunction;
if($self->{'context_replace'}) {
for my $n (0 .. $#args) {
$replace_context[$n]{$replacementfunction} =
$replace_context[$n]{$replacementfunction} =
$args[$n]->replace($replacementfunction);
}
} else {
CORE::push(@{$replace_multi{$replacementfunction}},
CORE::push(@{$replace_multi{$replacementfunction}},
map { $args[$_]->replace($replacementfunction) }
0 .. $#args);
}
@ -3238,7 +3255,6 @@ sub get {
} else {
push @out_record, Arg->new("");
}
}
return \@out_record;
} else {
@ -3348,7 +3364,7 @@ sub unget {
sub empty {
my $self = shift;
my $empty = (not @Global::unget_argv
my $empty = (not @Global::unget_argv
and not @{$self->{'unget'}});
for my $fh (@{$self->{'fhs'}}) {
$empty &&= eof($fh);
@ -3498,7 +3514,7 @@ sub release {
if($self->nlinks() == 1) {
unlink $self->{'idfile'};
rmdir $self->{'lockdir'};
}
}
$self->unlock();
}
::debug("released $self->{'pid'}\n");

View file

@ -246,18 +246,18 @@ Implies B<--semaphore>.
=item B<--cleanup>
Remove transferred files. B<--cleanup> will remove the transferred files
on the remote server after processing is done.
on the remote computer after processing is done.
find log -name '*gz' | parallel \
--sshlogin server.example.com --transfer --return {.}.bz2 \
--cleanup "zcat {} | bzip -9 >{.}.bz2"
With B<--transfer> the file transferred to the remote server will be
removed on the remote server. Directories created will not be removed
With B<--transfer> the file transferred to the remote computer will be
removed on the remote computer. Directories created will not be removed
- even if they are empty.
With B<--return> the file transferred from the remote server will be
removed on the remote server. Directories created will not be removed
With B<--return> the file transferred from the remote computer will be
removed on the remote computer. Directories created will not be removed
- even if they are empty.
B<--cleanup> is ignored when not used with B<--transfer> or B<--return>.
@ -493,12 +493,12 @@ Implies B<-X> unless B<-m> is set.
=item B<--load> I<max-load> (experimental)
Do not start new jobs on a given machine unless the load is less than
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%>
is a valid setting.
The load average is only sampled every 10 seconds to avoid stressing
small machines.
small computers.
=item B<--controlmaster> (experimental)
@ -610,8 +610,8 @@ with 'y' or 'Y'. Implies B<-t>.
Use profile I<profilename> for options. This is useful if you want to
have multiple profiles. You could have one profile for running jobs in
parallel on the local machine and a different profile for running jobs
on remote machines. See the section PROFILE FILES for examples.
parallel on the local computer and a different profile for running jobs
on remote computers. See the section PROFILE FILES for examples.
I<profilename> corresponds to the file ~/.parallel/I<profilename>.
@ -644,23 +644,23 @@ reason (such as network failure).
=item B<--return> I<filename>
Transfer files from remote servers. B<--return> is used with
B<--sshlogin> when the arguments are files on the remote servers. When
Transfer files from remote computers. B<--return> is used with
B<--sshlogin> when the arguments are files on the remote computers. When
processing is done the file I<filename> will be transferred
from the remote server using B<rsync> and will be put relative to
from the remote computer using B<rsync> and will be put relative to
the default login dir. E.g.
echo foo/bar.txt | parallel \
--sshlogin server.example.com --return {.}.out touch {.}.out
This will transfer the file I<$HOME/foo/bar.out> from the server
This will transfer the file I<$HOME/foo/bar.out> from the computer
I<server.example.com> to the file I<foo/bar.out> after running
B<touch foo/bar.out> on I<server.example.com>.
echo /tmp/foo/bar.txt | parallel \
--sshlogin server.example.com --return {.}.out touch {.}.out
This will transfer the file I</tmp/foo/bar.out> from the server
This will transfer the file I</tmp/foo/bar.out> from the computer
I<server.example.com> to the file I</tmp/foo/bar.out> after running
B<touch /tmp/foo/bar.out> on I<server.example.com>.
@ -742,9 +742,9 @@ when called with B<--shebang>).
=item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
Distribute jobs to remote servers. The jobs will be run on a list of
remote servers. GNU B<parallel> will determine the number of CPU
cores on the remote servers and run the number of jobs as specified by
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
cores on the remote computers and run the number of jobs as specified by
B<-j>. If the number I<ncpu> is given GNU B<parallel> will use this
number for number of CPU cores on the host. Normally I<ncpu> will not
be needed.
@ -803,6 +803,17 @@ Silent. The job to be run will not be printed. This is the default.
Can be reversed with B<-v>.
=item B<--tty> (beta testing)
=item B<-T> (beta testing)
Open terminal tty. If GNU B<parallel> is used for starting an
interactive program then this option may be needed. It will start only
one job at a time (i.e. B<-j1>), not buffer the output (i.e. B<-u>),
and it will open a tty for the job. When the job is done, the next job
will get the tty.
=item B<--tmpdir> I<dirname>
Directory for temporary files. GNU B<parallel> normally buffers output
@ -822,22 +833,22 @@ See also B<-v> and B<-p>.
=item B<--transfer>
Transfer files to remote servers. B<--transfer> is used with
Transfer files to remote computers. B<--transfer> is used with
B<--sshlogin> when the arguments are files and should be transferred to
the remote servers. The files will be transferred using B<rsync> and
the remote computers. The files will be transferred using B<rsync> and
will be put relative to the default login dir. E.g.
echo foo/bar.txt | parallel \
--sshlogin server.example.com --transfer wc
This will transfer the file I<foo/bar.txt> to the server
This will transfer the file I<foo/bar.txt> to the computer
I<server.example.com> to the file I<$HOME/foo/bar.txt> before running
B<wc foo/bar.txt> on I<server.example.com>.
echo /tmp/foo/bar.txt | parallel \
--sshlogin server.example.com --transfer wc
This will transfer the file I<foo/bar.txt> to the server
This will transfer the file I<foo/bar.txt> to the computer
I<server.example.com> to the file I</tmp/foo/bar.txt> before running
B<wc /tmp/foo/bar.txt> on I<server.example.com>.
@ -929,9 +940,9 @@ Print the version GNU B<parallel> and exit.
=item B<-W> I<mydir> (beta testing)
Files transferred using B<--transfer> and B<--return> will be relative
to I<mydir> on remote machines, and the command will be executed in
to I<mydir> on remote computers, and the command will be executed in
that dir. The special workdir B<...> will create a workdir in
B<~/.parallel/tmp/> on the remote machines and will be removed if
B<~/.parallel/tmp/> on the remote computers and will be removed if
using B<--cleanup>.
@ -1323,16 +1334,16 @@ GNU B<parallel> will try to determine the number of CPU cores on each
of the remote computers, so B<-j+0> will run one job per CPU core -
even if the remote computers do not have the same number of CPU cores.
If the number of CPU cores on the remote servers is not identified
If the number of CPU cores on the remote computers is not identified
correctly the number of CPU cores can be added in front. Here the
server has 8 CPU cores.
computer has 8 CPU cores.
seq 1 10 | parallel --sshlogin 8/server.example.com echo
=head1 EXAMPLE: Transferring of files
To recompress gzipped files with B<bzip2> using a remote server run:
To recompress gzipped files with B<bzip2> using a remote computer run:
find logs/ -name '*.gz' | \
parallel --sshlogin server.example.com \
@ -1363,7 +1374,7 @@ computer and the files transferred from the remote computer:
parallel --sshlogin server.example.com \
--transfer --return {.}.bz2 --cleanup "zcat {} | bzip2 -9 >{.}.bz2"
If you want run on several servers add the servers to I<--sshlogin>
If you want run on several computers add the computers to I<--sshlogin>
either using ',' or multiple I<--sshlogin>:
find logs/ -name '*.gz' | \
@ -1513,9 +1524,9 @@ same time:
You can use GNU Parallel to start interactive programs like emacs or vi:
B<cat filelist | parallel -uXj1 emacs>
B<cat filelist | parallel -T -X emacs>
B<cat filelist | parallel -uXj1 vi>
B<cat filelist | parallel -T -X vi>
If there are more files than will fit on a single command line, the
editor will be started again with the remaining files.
@ -1792,7 +1803,7 @@ Example: Profile for running a perl script before every command:
Note how the $ and " need to be quoted using \.
Example: Profile for running distributed jobs with B<nice> on the
remote machines:
remote computers:
echo -S .. nice > ~/.parallel/dist
parallel -J dist --trc {.}.bz2 bzip2 -9 ::: *
@ -2385,14 +2396,14 @@ using GNU B<parallel>:
ClusterSSH solves a different problem than GNU B<parallel>.
ClusterSSH runs the same command with the same arguments on a list of
machines - one per machine. This is typically used for administrating
several machines that are almost identical.
computers - one per computer. This is typically used for administrating
several computers that are almost identical.
GNU B<parallel> runs the same (or different) commands with different
arguments in parallel possibly using remote machines to help
computing. If more than one machine is listed in B<-S> GNU B<parallel> may
arguments in parallel possibly using remote computers to help
computing. If more than one computer is listed in B<-S> GNU B<parallel> may
only use one of these (e.g. if there are 8 jobs to be run and one
machine has 8 cores).
computer has 8 cores).
GNU B<parallel> can be used as a poor-man's version of ClusterSSH:

View file

@ -81,6 +81,17 @@ available.
done
sem --wait
=head1 EXAMPLE: Protecting pod2html from itself
pod2html creates two files: pod2htmd.tmp and pod2htmi.tmp which it
does not clean up. It uses these two files for a short time. But if
you run multiple pod2html in parallel (e.g. in a Makefile with make
-j) you need to protect pod2html from running twice at the same
time. B<sem> running as a mutex will do just that:
sem --fg --id pod2html pod2html foo.pod > foo.html
sem --fg --id pod2html rm -f pod2htmd.tmp pod2htmi.tmp
=head1 BUGS

View file

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

View file

@ -91,7 +91,7 @@ echo 3 | xargs -P 1 -n 1 -a files cat -
echo 'parallel Expect: 3 1 via psedotty 2'
cat >/tmp/parallel-script-for-script <<EOF
#!/bin/bash
echo 3 | parallel -k -P 1 -n 1 -a files cat -
echo 3 | parallel -T -k -P 1 -n 1 -a files cat -
EOF
chmod 755 /tmp/parallel-script-for-script
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script /dev/null
@ -102,7 +102,7 @@ echo 3 | xargs -I {} -P 1 -n 1 -a files cat {} -
echo 'parallel Expect: 1 3 2 via pseudotty'
cat >/tmp/parallel-script-for-script2 <<EOF
#!/bin/bash
echo 3 | parallel -k -I {} -P 1 -n 1 -a files cat {} -
echo 3 | parallel -T -k -I {} -P 1 -n 1 -a files cat {} -
EOF
chmod 755 /tmp/parallel-script-for-script2
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script2 /dev/null

View file

@ -13,7 +13,7 @@ parallel --argsep .--- -kv .--- 'echo a' 'echo b'
echo '### Test stdin goes to first command only ("-" as argument)'
cat >/tmp/parallel-script-for-script <<EOF
#!/bin/bash
echo via first cat |parallel -kv cat ::: - -
echo via first cat |parallel -T -kv cat ::: - -
EOF
chmod 755 /tmp/parallel-script-for-script
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script /dev/null
@ -21,7 +21,7 @@ sleep 1
echo '### Test stdin goes to first command only ("cat" as argument)'
cat >/tmp/parallel-script-for-script2 <<EOF
#!/bin/bash
echo no output |parallel -kv ::: 'echo a' 'cat'
echo no output |parallel -T -kv ::: 'echo a' 'cat'
EOF
chmod 755 /tmp/parallel-script-for-script2
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script2 /dev/null

View file

@ -0,0 +1,170 @@
#!/bin/bash
SERVER1=parallel-server3
SERVER2=parallel-server2
# Minimal version of test17
# Make sure sort order is the same
export LANG=C
echo '### Test --transfer --return --cleanup'
rm -rf /tmp/parallel.file*
stdout ssh $SERVER1 rm -rf 'tmp/parallel.file*' '/tmp/parallel.file*'
stdout ssh parallel@$SERVER2 rm -rf 'tmp/parallel.file*' '/tmp/parallel.file*'
(seq 1 2) >/tmp/test17
echo '# Create some weirdly files in /tmp'
mkdir -p /tmp/parallel.file
cat /tmp/test17 | parallel -k /bin/echo file{} '>'/tmp/parallel.file{}.file
cat /tmp/test17 | parallel -k /bin/echo /tmp/parallel.file{}.file >/tmp/test17abs
cat /tmp/test17 | parallel -k /bin/echo tmp/parallel.file{}.file >/tmp/test17rel
echo '### --transfer - abspath'
stdout ssh $SERVER1 'rm -rf /tmp/parallel.file*'
stdout ssh parallel@$SERVER2 'rm -rf /tmp/parallel.file*'
cat /tmp/test17abs | parallel -k --transfer --sshlogin $SERVER1,parallel@$SERVER2 cat {}";"rm {}
# One of these should give the empty dir /tmp/parallel.file
echo good if no file
stdout ssh $SERVER1 ls '/tmp/parallel.file*'
# The other: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*'
echo '### --transfer - relpath'
stdout ssh $SERVER1 'rm -rf tmp/parallel.file*'
stdout ssh parallel@$SERVER2 'rm -rf tmp/parallel.file*'
cd /
cat /tmp/test17rel | parallel -k --transfer --sshlogin $SERVER1,parallel@$SERVER2 cat {}";"rm {}
# Should give: No such file or directory
echo good if no file
stdout ssh $SERVER1 ls 'tmp/parallel.file*'
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*'
echo '### --transfer --cleanup - abspath'
cat /tmp/test17abs | parallel -k --transfer --cleanup --sshlogin $SERVER1,parallel@$SERVER2 cat {}
echo good if no file
# Should give: No such file or directory
stdout ssh $SERVER1 ls '/tmp/parallel.file*'
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*'
echo '### --transfer --cleanup - relpath'
cat /tmp/test17rel | parallel -k --transfer --cleanup --sshlogin $SERVER1,parallel@$SERVER2 cat {}
# Should give: No such file or directory
echo good if no file
stdout ssh $SERVER1 ls 'tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*' || echo OK
echo '### --return - abspath'
rm -rf /tmp/parallel.file*out
cat /tmp/test17abs | parallel -k --return {.}.out --sshlogin $SERVER1,parallel@$SERVER2 echo {} ">"{.}.out
ls /tmp/parallel.file*out
echo '### --return - relpath'
rm -rf /tmp/parallel.file*out
cat /tmp/test17rel | parallel -k --return {.}.out --sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp/parallel.file ';'echo {} ">"{.}.out
ls tmp/parallel.file*out
echo '### --return - multiple files'
rm -rf tmp/parallel.file*out tmp/parallel.file*done
cat /tmp/test17rel | parallel -k --return {.}.out --return {}.done \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp ';'echo {} ">"{.}.out';'echo {} ">"{}.done';'
ls tmp/parallel.file*out tmp/parallel.file*done
echo '### --return --cleanup - abspath'
rm -rf /tmp/parallel.file*out /tmp/parallel.file*done
cat /tmp/test17abs | parallel -k --return {.}.out --return {}.done --cleanup \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp/parallel.file ';'echo {} ">"{.}.out';'echo {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls '/tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*' || echo OK
echo '### --return --cleanup - relpath'
rm -rf tmp/parallel.file*out tmp/parallel.file*done
cat /tmp/test17rel | parallel -k --return {.}.out --return {}.done --cleanup \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp/parallel.file ';'echo {} ">"{.}.out';'echo {} ">"{}.done';'
ls tmp/parallel.file*out tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls 'tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*' || echo OK
echo '### --return --cleanup - multiple returns'
rm -rf tmp/parallel.file*out tmp/parallel.file*done
cat /tmp/test17rel | parallel -k --return {.}.out --return {}.done --cleanup \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp/parallel.file ';'echo {} ">"{.}.out';'echo {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls 'tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*' || echo OK
echo '### --transfer --return --cleanup - abspath'
rm -rf /tmp/parallel.file*out /tmp/parallel.file*done
cat /tmp/test17abs | parallel -k --transfer --return {.}.out --return {}.done --cleanup \
--sshlogin $SERVER1,parallel@$SERVER2 cat {} ">"{.}.out';'cat {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls '/tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*' || echo OK
echo '### --transfer --return --cleanup - relpath'
rm -rf tmp/parallel.file*out tmp/parallel.file*done
cat /tmp/test17rel | parallel -k --transfer --return {.}.out --return {}.done --cleanup \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp ';'cat {} ">"{.}.out';'cat {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls 'tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*' || echo OK
echo '### --transfer --return --cleanup - multiple files'
rm -rf tmp/parallel.file*out tmp/parallel.file*done
cat /tmp/test17rel | parallel -k --transfer --return {.}.out --return {}.done --cleanup \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp ';'cat {} ">"{.}.out';'cat {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
stdout ssh $SERVER1 ls 'tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*' || echo OK
echo '### --trc - abspath'
rm -rf /tmp/parallel.file*out /tmp/parallel.file*done
cat /tmp/test17abs | parallel -k --trc {.}.out --trc {}.done \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp ';'cat {} ">"{.}.out';'cat {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls '/tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*' || echo OK
echo '### --trc - relpath'
rm -rf tmp/parallel.file*out tmp/parallel.file*done
cat /tmp/test17rel | parallel -k --trc {.}.out --trc {}.done \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp ';'cat {} ">"{.}.out';'cat {} ">"{}.done';'
ls tmp/parallel.file*out tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls 'tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls 'tmp/parallel.file*' || echo OK
echo '### --trc - multiple files'
rm -rf /tmp/parallel.file*out /tmp/parallel.file*done
cat /tmp/test17abs | parallel -k --trc {.}.out --trc {}.done \
--sshlogin $SERVER1,parallel@$SERVER2 mkdir -p tmp ';'cat {} ">"{.}.out';'cat {} ">"{}.done';'
ls /tmp/parallel.file*out /tmp/parallel.file*done
echo good if no file
stdout ssh $SERVER1 ls '/tmp/parallel.file*' || echo OK
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*' || echo OK
echo '### --transfer --cleanup - multiple argument files'
parallel -kv --transfer --cleanup -Sparallel@$SERVER2 cat {2} {1} :::: /tmp/test17rel <(sort -r /tmp/test17abs)
# Should give: No such file or directory
stdout ssh parallel@$SERVER2 ls '/tmp/parallel.file*' || echo OK

View file

@ -85,7 +85,7 @@ parallel-server3 rsync --server --sender -lDrRze.iLsf --remove-source-files . ./
'newline2.out
parallel-server3 rsync --server --sender -lDrRze.iLsf --remove-source-files . ././tmp/parallel.file.'
'newline2.out2
parallel-server3 rm -f tmp/parallel.file.'
parallel-server3 rm -f ./tmp/parallel.file.'
'newline2; rmdir 2>/dev/null ./tmp
-l parallel parallel-server2 rsync --server -lDErRze.iLsf . .
parallel@parallel-server2 PARALLEL_SEQ=1;export PARALLEL_SEQ;PARALLEL_PID=00000;export PARALLEL_PID; cat tmp/parallel.file.'
@ -97,7 +97,7 @@ parallel@parallel-server2 PARALLEL_SEQ=1;export PARALLEL_SEQ;PARALLEL_PID=00000;
'newline1.out
-l parallel parallel-server2 rsync --server --sender -lDrRze.iLsf --remove-source-files . ././tmp/parallel.file.'
'newline1.out2
parallel@parallel-server2 rm -f tmp/parallel.file.'
parallel@parallel-server2 rm -f ./tmp/parallel.file.'
'newline1; rmdir 2>/dev/null ./tmp
### Test use special ssh with > 9 simultaneous
1

View file

@ -0,0 +1,127 @@
### Test --transfer --return --cleanup
# Create some weirdly files in /tmp
### --transfer - abspath
file1
file2
good if no file
ls: cannot access /tmp/parallel.file*: No such file or directory
ls: cannot access /tmp/parallel.file*: No such file or directory
### --transfer - relpath
file1
file2
good if no file
ls: cannot access tmp/parallel.file*: No such file or directory
ls: cannot access tmp/parallel.file*: No such file or directory
### --transfer --cleanup - abspath
file1
file2
good if no file
ls: cannot access /tmp/parallel.file*: No such file or directory
ls: cannot access /tmp/parallel.file*: No such file or directory
### --transfer --cleanup - relpath
file1
file2
good if no file
ls: cannot access tmp/parallel.file*: No such file or directory
OK
ls: cannot access tmp/parallel.file*: No such file or directory
OK
### --return - abspath
/tmp/parallel.file1.out
/tmp/parallel.file2.out
### --return - relpath
tmp/parallel.file1.out
tmp/parallel.file2.out
### --return - multiple files
tmp/parallel.file1.file.done
tmp/parallel.file1.out
tmp/parallel.file2.file.done
tmp/parallel.file2.out
### --return --cleanup - abspath
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
good if no file
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
### --return --cleanup - relpath
tmp/parallel.file1.file.done
tmp/parallel.file1.out
tmp/parallel.file2.file.done
tmp/parallel.file2.out
good if no file
ls: cannot access tmp/parallel.file*: No such file or directory
OK
### --return --cleanup - multiple returns
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
good if no file
ls: cannot access tmp/parallel.file*: No such file or directory
OK
### --transfer --return --cleanup - abspath
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
good if no file
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
### --transfer --return --cleanup - relpath
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
good if no file
ls: cannot access tmp/parallel.file*: No such file or directory
OK
### --transfer --return --cleanup - multiple files
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
ls: cannot access tmp/parallel.file*: No such file or directory
OK
### --trc - abspath
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
good if no file
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
### --trc - relpath
tmp/parallel.file1.file.done
tmp/parallel.file1.out
tmp/parallel.file2.file.done
tmp/parallel.file2.out
good if no file
ls: cannot access tmp/parallel.file*: No such file or directory
OK
### --trc - multiple files
/tmp/parallel.file1.file.done
/tmp/parallel.file1.out
/tmp/parallel.file2.file.done
/tmp/parallel.file2.out
good if no file
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
ls: cannot access /tmp/parallel.file*: No such file or directory
OK
### --transfer --cleanup - multiple argument files
cat /tmp/parallel.file2.file tmp/parallel.file1.file
file2
file1
cat /tmp/parallel.file1.file tmp/parallel.file2.file
file1
file2
ls: cannot access /tmp/parallel.file*: No such file or directory
OK