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 = = Presentation of GNU Parallel =
GNU Parallel is a shell tool for executing jobs in parallel using one 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 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 typical input is a list of files, a list of hosts, a list of users, or
a list of tables. a list of tables.

20
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # 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>. # Report bugs to <bug-parallel@gnu.org>.
# #
@ -551,8 +551,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='parallel' PACKAGE_NAME='parallel'
PACKAGE_TARNAME='parallel' PACKAGE_TARNAME='parallel'
PACKAGE_VERSION='20101206' PACKAGE_VERSION='20101220'
PACKAGE_STRING='parallel 20101206' PACKAGE_STRING='parallel 20101220'
PACKAGE_BUGREPORT='bug-parallel@gnu.org' PACKAGE_BUGREPORT='bug-parallel@gnu.org'
PACKAGE_URL='' 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. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF 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]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1234,7 +1234,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of parallel 20101206:";; short | recursive ) echo "Configuration of parallel 20101220:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1301,7 +1301,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
parallel configure 20101206 parallel configure 20101220
generated by GNU Autoconf 2.67 generated by GNU Autoconf 2.67
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2010 Free Software Foundation, Inc.
@ -1318,7 +1318,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. 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 generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@ $ $0 $@
@ -2133,7 +2133,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='parallel' PACKAGE='parallel'
VERSION='20101206' VERSION='20101220'
cat >>confdefs.h <<_ACEOF 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 # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" 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 generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -2746,7 +2746,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
parallel config.status 20101206 parallel config.status 20101220
configured by $0, generated by GNU Autoconf 2.67, configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\" 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]) AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([ 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: Til QUOTING:
FN="two spaces" FN="two spaces"
@ -309,7 +312,8 @@ distribute the arguments evenly if running -X.
=head1 options =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 =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 rm -rf src/Makefile.in
autoreconf --install -W gnu autoreconf --install -W gnu
./configure ./configure
make && sudo make install make -j && sudo make install
== Testsuite == == 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/
http://www.gnu.org/software/parallel/man.html 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/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 cd ../parallel-web/parallel
cvs up cvs up
cvs ci 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>, Andrew McFague <amcfague@wgen.net>, Steven M. Christensen <sunfreeware@gmail.com>,
Chris Howey <howeyc@gmail.com>, Fethican Coşkuner <fethicanc@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>, 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/ download at: http://ftp.gnu.org/gnu/parallel/
New in this release: New in this release:
@ -146,13 +153,26 @@ New in this release:
* Implemented --nice set the niceness of jobs running both locally and * Implemented --nice set the niceness of jobs running both locally and
remotely. 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 * Review with focus on clusters. Thanks to Taylor Gillespie
http://www.unixpronews.com/unixpronews-49-20101019GNUParallelSpeedUpProcessingWithMulticoresClusters.html 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 = = About GNU Parallel =
GNU Parallel is a shell tool for executing jobs in parallel using one 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 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 typical input is a list of files, a list of hosts, a list of users, a
list of URLs, or a list of tables. 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)' \ pod2man --release='$(PACKAGE_VERSION)' --center='$(PACKAGE_NAME)' \
--section=1 $(srcdir)/niceload > $(srcdir)/niceload.1 --section=1 $(srcdir)/niceload > $(srcdir)/niceload.1
parallel.html: parallel Makefile parallel.html: parallel Makefile sem
pod2html $(srcdir)/parallel > $(srcdir)/parallel.html ./sem --fg --id pod2html pod2html $(srcdir)/parallel.pod > $(srcdir)/parallel.html
rm -f $(srcdir)/pod2htm* ./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sem.html: sem.pod Makefile sem.html: sem.pod Makefile sem
pod2html $(srcdir)/sem.pod > $(srcdir)/sem.html ./sem --fg --id pod2html pod2html $(srcdir)/sem.pod > $(srcdir)/sem.html
rm -f $(srcdir)/pod2htm* ./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sql.html: sql Makefile sql.html: sql Makefile sem
pod2html $(srcdir)/sql > $(srcdir)/sql.html ./sem --fg --id pod2html pod2html $(srcdir)/sql > $(srcdir)/sql.html
rm -f $(srcdir)/pod2htm* ./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
niceload.html: niceload Makefile niceload.html: niceload Makefile sem
pod2html $(srcdir)/niceload > $(srcdir)/niceload.html ./sem --fg --id pod2html pod2html $(srcdir)/niceload > $(srcdir)/niceload.html
rm -f $(srcdir)/pod2htm* ./sem --fg --id pod2html rm -f $(srcdir)/pod2htm*
sem: parallel sem: parallel
ln -fs parallel sem ln -fs parallel sem

View file

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

View file

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

View file

@ -246,18 +246,18 @@ Implies B<--semaphore>.
=item B<--cleanup> =item B<--cleanup>
Remove transferred files. B<--cleanup> will remove the transferred files 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 \ find log -name '*gz' | parallel \
--sshlogin server.example.com --transfer --return {.}.bz2 \ --sshlogin server.example.com --transfer --return {.}.bz2 \
--cleanup "zcat {} | bzip -9 >{.}.bz2" --cleanup "zcat {} | bzip -9 >{.}.bz2"
With B<--transfer> the file transferred to the remote server will be With B<--transfer> the file transferred to the remote computer will be
removed on the remote server. Directories created will not be removed removed on the remote computer. Directories created will not be removed
- even if they are empty. - even if they are empty.
With B<--return> the file transferred from the remote server will be With B<--return> the file transferred from the remote computer will be
removed on the remote server. Directories created will not be removed removed on the remote computer. Directories created will not be removed
- even if they are empty. - even if they are empty.
B<--cleanup> is ignored when not used with B<--transfer> or B<--return>. 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) =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%> I<max-load>. I<max-load> uses the same syntax as B<--jobs>, so I<100%>
is a valid setting. is a valid setting.
The load average is only sampled every 10 seconds to avoid stressing The load average is only sampled every 10 seconds to avoid stressing
small machines. small computers.
=item B<--controlmaster> (experimental) =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 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 have multiple profiles. You could have one profile for running jobs in
parallel on the local machine and a different profile for running jobs parallel on the local computer and a different profile for running jobs
on remote machines. See the section PROFILE FILES for examples. on remote computers. See the section PROFILE FILES for examples.
I<profilename> corresponds to the file ~/.parallel/I<profilename>. I<profilename> corresponds to the file ~/.parallel/I<profilename>.
@ -644,23 +644,23 @@ reason (such as network failure).
=item B<--return> I<filename> =item B<--return> I<filename>
Transfer files from remote servers. B<--return> is used with Transfer files from remote computers. B<--return> is used with
B<--sshlogin> when the arguments are files on the remote servers. When B<--sshlogin> when the arguments are files on the remote computers. When
processing is done the file I<filename> will be transferred 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. the default login dir. E.g.
echo foo/bar.txt | parallel \ echo foo/bar.txt | parallel \
--sshlogin server.example.com --return {.}.out touch {.}.out --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 I<server.example.com> to the file I<foo/bar.out> after running
B<touch foo/bar.out> on I<server.example.com>. B<touch foo/bar.out> on I<server.example.com>.
echo /tmp/foo/bar.txt | parallel \ echo /tmp/foo/bar.txt | parallel \
--sshlogin server.example.com --return {.}.out touch {.}.out --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 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>. 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[,...]]> =item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
Distribute jobs to remote servers. The jobs will be run on a list of Distribute jobs to remote computers. The jobs will be run on a list of
remote servers. GNU B<parallel> will determine the number of CPU remote computers. GNU B<parallel> will determine the number of CPU
cores on the remote servers and run the number of jobs as specified by 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 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 number for number of CPU cores on the host. Normally I<ncpu> will not
be needed. 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>. 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> =item B<--tmpdir> I<dirname>
Directory for temporary files. GNU B<parallel> normally buffers output Directory for temporary files. GNU B<parallel> normally buffers output
@ -822,22 +833,22 @@ See also B<-v> and B<-p>.
=item B<--transfer> =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 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. will be put relative to the default login dir. E.g.
echo foo/bar.txt | parallel \ echo foo/bar.txt | parallel \
--sshlogin server.example.com --transfer wc --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 I<server.example.com> to the file I<$HOME/foo/bar.txt> before running
B<wc foo/bar.txt> on I<server.example.com>. B<wc foo/bar.txt> on I<server.example.com>.
echo /tmp/foo/bar.txt | parallel \ echo /tmp/foo/bar.txt | parallel \
--sshlogin server.example.com --transfer wc --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 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>. 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) =item B<-W> I<mydir> (beta testing)
Files transferred using B<--transfer> and B<--return> will be relative 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 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>. 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 - 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. 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 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 seq 1 10 | parallel --sshlogin 8/server.example.com echo
=head1 EXAMPLE: Transferring of files =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' | \ find logs/ -name '*.gz' | \
parallel --sshlogin server.example.com \ parallel --sshlogin server.example.com \
@ -1363,7 +1374,7 @@ computer and the files transferred from the remote computer:
parallel --sshlogin server.example.com \ parallel --sshlogin server.example.com \
--transfer --return {.}.bz2 --cleanup "zcat {} | bzip2 -9 >{.}.bz2" --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>: either using ',' or multiple I<--sshlogin>:
find logs/ -name '*.gz' | \ find logs/ -name '*.gz' | \
@ -1513,9 +1524,9 @@ same time:
You can use GNU Parallel to start interactive programs like emacs or vi: 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 If there are more files than will fit on a single command line, the
editor will be started again with the remaining files. 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 \. Note how the $ and " need to be quoted using \.
Example: Profile for running distributed jobs with B<nice> on the Example: Profile for running distributed jobs with B<nice> on the
remote machines: remote computers:
echo -S .. nice > ~/.parallel/dist echo -S .. nice > ~/.parallel/dist
parallel -J dist --trc {.}.bz2 bzip2 -9 ::: * 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 solves a different problem than GNU B<parallel>.
ClusterSSH runs the same command with the same arguments on a list of ClusterSSH runs the same command with the same arguments on a list of
machines - one per machine. This is typically used for administrating computers - one per computer. This is typically used for administrating
several machines that are almost identical. several computers that are almost identical.
GNU B<parallel> runs the same (or different) commands with different GNU B<parallel> runs the same (or different) commands with different
arguments in parallel possibly using remote machines to help arguments in parallel possibly using remote computers to help
computing. If more than one machine is listed in B<-S> GNU B<parallel> may 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 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: GNU B<parallel> can be used as a poor-man's version of ClusterSSH:

View file

@ -81,6 +81,17 @@ available.
done done
sem --wait 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 =head1 BUGS

View file

@ -528,7 +528,7 @@ $Global::Initfile && unlink $Global::Initfile;
exit ($err); exit ($err);
sub parse_options { sub parse_options {
$Global::version = 20101206; $Global::version = 20101220;
$Global::progname = 'sql'; $Global::progname = 'sql';
# This must be done first as this may exec myself # 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' echo 'parallel Expect: 3 1 via psedotty 2'
cat >/tmp/parallel-script-for-script <<EOF cat >/tmp/parallel-script-for-script <<EOF
#!/bin/bash #!/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 EOF
chmod 755 /tmp/parallel-script-for-script chmod 755 /tmp/parallel-script-for-script
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script /dev/null 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' echo 'parallel Expect: 1 3 2 via pseudotty'
cat >/tmp/parallel-script-for-script2 <<EOF cat >/tmp/parallel-script-for-script2 <<EOF
#!/bin/bash #!/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 EOF
chmod 755 /tmp/parallel-script-for-script2 chmod 755 /tmp/parallel-script-for-script2
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script2 /dev/null 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)' echo '### Test stdin goes to first command only ("-" as argument)'
cat >/tmp/parallel-script-for-script <<EOF cat >/tmp/parallel-script-for-script <<EOF
#!/bin/bash #!/bin/bash
echo via first cat |parallel -kv cat ::: - - echo via first cat |parallel -T -kv cat ::: - -
EOF EOF
chmod 755 /tmp/parallel-script-for-script chmod 755 /tmp/parallel-script-for-script
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script /dev/null 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)' echo '### Test stdin goes to first command only ("cat" as argument)'
cat >/tmp/parallel-script-for-script2 <<EOF cat >/tmp/parallel-script-for-script2 <<EOF
#!/bin/bash #!/bin/bash
echo no output |parallel -kv ::: 'echo a' 'cat' echo no output |parallel -T -kv ::: 'echo a' 'cat'
EOF EOF
chmod 755 /tmp/parallel-script-for-script2 chmod 755 /tmp/parallel-script-for-script2
echo via pseudotty | script -q -f -c /tmp/parallel-script-for-script2 /dev/null 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 'newline2.out
parallel-server3 rsync --server --sender -lDrRze.iLsf --remove-source-files . ././tmp/parallel.file.' parallel-server3 rsync --server --sender -lDrRze.iLsf --remove-source-files . ././tmp/parallel.file.'
'newline2.out2 'newline2.out2
parallel-server3 rm -f tmp/parallel.file.' parallel-server3 rm -f ./tmp/parallel.file.'
'newline2; rmdir 2>/dev/null ./tmp 'newline2; rmdir 2>/dev/null ./tmp
-l parallel parallel-server2 rsync --server -lDErRze.iLsf . . -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.' 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 'newline1.out
-l parallel parallel-server2 rsync --server --sender -lDrRze.iLsf --remove-source-files . ././tmp/parallel.file.' -l parallel parallel-server2 rsync --server --sender -lDrRze.iLsf --remove-source-files . ././tmp/parallel.file.'
'newline1.out2 'newline1.out2
parallel@parallel-server2 rm -f tmp/parallel.file.' parallel@parallel-server2 rm -f ./tmp/parallel.file.'
'newline1; rmdir 2>/dev/null ./tmp 'newline1; rmdir 2>/dev/null ./tmp
### Test use special ssh with > 9 simultaneous ### Test use special ssh with > 9 simultaneous
1 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