From 2ff435caea882d7d7ff6677a2f70a913e85a93d8 Mon Sep 17 00:00:00 2001 From: Ole Tange Date: Fri, 24 Oct 2014 11:30:39 +0200 Subject: [PATCH] parallel: sub wrapper implemented. Passed most of the testsuite. --- doc/release_new_version | 43 +---- src/niceload | 4 +- src/niceload.pod | 10 +- src/parallel | 221 ++++++++++++---------- src/parallel.pod | 18 +- src/sql | 2 +- testsuite/tests-to-run/test13.sh | 2 +- testsuite/wanted-results/parallel-local13 | 3 + testsuite/wanted-results/test19 | 46 ++--- 9 files changed, 170 insertions(+), 179 deletions(-) diff --git a/doc/release_new_version b/doc/release_new_version index 003679e1..6738a709 100644 --- a/doc/release_new_version +++ b/doc/release_new_version @@ -225,53 +225,18 @@ cc:Tim Cuthbertson , Ryoichiro Suzuki , Jesse Alama -Subject: GNU Parallel 20141022 ('Shellshock') released +Subject: GNU Parallel 20141122 ('') released -GNU Parallel 20141022 ('Shellshock') has been released. It is available for download at: http://ftp.gnu.org/gnu/parallel/ - -Shellshock has also hit GNU Parallel. It is not a security issue, per se (the security issue was in Bash), but Bash's solution affects --env when exporting a function. +GNU Parallel 20141122 ('') has been released. It is available for download at: http://ftp.gnu.org/gnu/parallel/ Haiku of the month: -Shellshock pain hits us. -Dash dash env is affected. -Upgrade Parallel. - -- Ole Tange +<<>> -(Last month's haiku was by Malcolm Cook) +A central piece of command generation was rewritten making this release alpha quality. New in this release: -* --env was changed to deal with Bash's new way of exporting a function. - -* GNU Parallel was cited in: Exclusion of cosmic rays in protoplanetary disks. II. Chemical gradients and observational signatures http://iopscience.iop.org/0004-637X/794/2/123/article - -* GNU Parallel was cited in: Application of Machine Learning to Algorithm Selection for TSP http://www.dbai.tuwien.ac.at/staff/musliu/art_ictai_cam.pdf - -* GNU Parallel was cited in: Performance Models for LTE-Advanced Random Access http://repository.asu.edu/attachments/137242/content/Tyagi_asu_0010E_14116.pdf - -* GNU Parallel was used (unfortunately without citation) in: De Novo Insertions and Deletions of Predominantly Paternal Origin Are Associated with Autism Spectrum Disorder http://www.cell.com/cms/attachment/2019079667/2039310868/mmc1.pdf - -* GNU Parallel was determined 'popular' by Statistical Analysis of Popular Open Source Software Projects and Their Communities http://andiwre.itmaranatha.org/prosiding/ICITEE2014/PaperAndiWRE-ICITEE2014.pdf - -* GNU Parallel is demonstrated in: Data Science at the Command Line: Facing the Future with Time-Tested Tools - -* GNU Parallel was covered in a talk at Sydney Perl Mongers group http://www.openfusion.net/talks/pwp/#24 - -* GNU Parallel and how to get started with it http://www.jduck.net/blog/2014/09/30/gnu-paralell/ - -* Behat/Selenium/Parallel http://jaffamonkey.com/behat-selenium-parallel/ - -* Comparing Golang, Scala, Elixir and Ruby for ETL http://www.dimroc.com/2014/09/29/etl-language-showdown/ - -* Parallelizing Batch Jobs for Fun and Profit http://mikeseidle.com/tech/programming/2013/03/parallelizing-batch-jobs - -* Assemble a list of which of these hosts are up or down http://opsfun.wordpress.com/2014/03/31/gnu-parallel/ - -* Running commands on many nodes simultaneously http://opsfun.wordpress.com/2014/03/31/19/ - -* Ubuntu 13.04でGNU ParallelをGNUモードで動かす http://qiita.com/YusukeSuzuki@github/items/7b96b5876bf980f21e85 - * Bug fixes and man page updates. GNU Parallel - For people who live life in the parallel lane. diff --git a/src/niceload b/src/niceload index ddb441e2..e2fa6dc4 100755 --- a/src/niceload +++ b/src/niceload @@ -24,7 +24,7 @@ use strict; use Getopt::Long; $Global::progname="niceload"; -$Global::version = 20141022; +$Global::version = 20141023; Getopt::Long::Configure("bundling","require_order"); get_options_from_array(\@ARGV) || die_usage(); if($opt::version) { @@ -886,4 +886,4 @@ sub io_status_darwin { return ::min($io, 10); } -$::exitsignal = $::exitstatus = 0; # Dummy +$::exitsignal = $::exitstatus = $opt::battery = 0; # Dummy diff --git a/src/niceload.pod b/src/niceload.pod index 59024eec..d776bf8f 100644 --- a/src/niceload.pod +++ b/src/niceload.pod @@ -101,17 +101,17 @@ B<--noswap> will set both B<--start-noswap> and B. Sets niceness. See B(1). -=item B<-p> I (beta testing) +=item B<-p> I -=item B<--pid> I (beta testing) +=item B<--pid> I Process ID of process to suspend. You can specify multiple process IDs with multiple B<-p> I. -=item B<--prg> I (beta testing) +=item B<--prg> I -=item B<--program> I (beta testing) +=item B<--program> I Name of running program to suspend. You can specify multiple programs with multiple B<--prg> I. @@ -141,7 +141,7 @@ Run limit. The running program will be slowed down if the system is above the limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>. -=item B<--sensor> I (beta testing) +=item B<--sensor> I Read sensor. Use I to read a sensor. diff --git a/src/parallel b/src/parallel index 82f926d3..dac10ecd 100755 --- a/src/parallel +++ b/src/parallel @@ -123,8 +123,7 @@ if($opt::eta or $opt::bar) { $Global::JobQueue->total_jobs(); } if($opt::pipepart) { - @Global::cat_partials = - map { pipe_part_files($_) } @opt::a; + @Global::cat_partials = map { pipe_part_files($_) } @opt::a; # Unget the command as many times as there are parts $Global::JobQueue->{'commandlinequeue'}->unget( map { $Global::JobQueue->{'commandlinequeue'}->get() } @Global::cat_partials @@ -772,7 +771,7 @@ sub get_options_from_array { sub parse_options { # Returns: N/A # Defaults: - $Global::version = 20141022; + $Global::version = 20141023; $Global::progname = 'parallel'; $Global::infinity = 2**31; $Global::debug = 0; @@ -5368,6 +5367,97 @@ sub total_failed { return ($total_failures); } +sub wrapped { + # Wrap command with: + # * --shellquote + # * --nice + # * --cat + # * --fifo + # * --sshlogin + # * --pipepart (@Global::cat_partials) + # * --pipe + # * --tmux + # The ordering of the wrapping is important: + # * --nice/--cat/--fifo should be done on the remote machine + # * --pipepart/--pipe should be done on the local machine inside --tmux + # Uses: + # $Global::envvar + # $opt::shellquote + # $opt::nice + # $Global::shell + # $opt::cat + # $opt::fifo + # @Global::cat_partials + # $opt::pipe + # $opt::tmux + # Returns: + # $self->{'wrapped'} = the command wrapped with the above + my $self = shift; + if(not defined $self->{'wrapped'}) { + my $command = $Global::envvar.$self->replaced(); + if($opt::shellquote) { + # Prepend echo + # and quote twice + $command = "echo " . + ::shell_quote_scalar(::shell_quote_scalar($command)); + } + if($opt::nice) { + # Prepend \nice -n19 $SHELL -c + # and quote. + # The '\' before nice is needed to avoid tcsh's built-in + $command = '\nice'. " -n". $opt::nice. " ". + $Global::shell. " -c ". + ::shell_quote_scalar($command); + } + if($opt::cat) { + # Prepend 'cat > {};' + # Append '_EXIT=$?;(rm {};exit $_EXIT)' + $command = + $self->{'commandline'}->replace_placeholders(["cat > \257<\257>; "], 0, 0). + $command. + $self->{'commandline'}->replace_placeholders( + ["; _EXIT=\$?; rm \257<\257>; exit \$_EXIT"], 0, 0); + } elsif($opt::fifo) { + # Prepend 'mkfifo {}; (' + # Append ') & _PID=$!; cat > {}; wait $_PID; _EXIT=$?;(rm {};exit $_EXIT)' + $command = + $self->{'commandline'}->replace_placeholders(["mkfifo \257<\257>; ("], 0, 0). + $command. + $self->{'commandline'}->replace_placeholders([") & _PID=\$!; cat > \257<\257>; ", + "wait \$_PID; _EXIT=\$?; ", + "rm \257<\257>; exit \$_EXIT"], + 0,0); + } + # Wrap with ssh + tranferring of files + $command = $self->sshlogin_wrap($command); + if(@Global::cat_partials) { + # Prepend: + # < /tmp/foo perl -e 'while(@ARGV) { sysseek(STDIN,shift,0) || die; $left = shift; while($read = sysread(STDIN,$buf, ($left > 32768 ? 32768 : $left))){ $left -= $read; syswrite(STDOUT,$buf); } }' 0 0 0 11 | + $command = (shift @Global::cat_partials). "|". "(". $command. ")"; + } elsif($opt::pipe) { + # Prepend EOF-detector to avoid starting $command if EOF. + # The $tmpfile might exist if run on a remote system - we accept that risk + my ($dummy_fh, $tmpfile) = ::tmpfile(SUFFIX => ".chr"); + # Unlink to avoid leaving files if --dry-run or --sshlogin + unlink $tmpfile; + $command = + # Exit value: + # empty input = true + # some input = exit val from command + qq{ sh -c 'dd bs=1 count=1 of=$tmpfile 2>/dev/null'; }. + qq{ test \! -s "$tmpfile" && rm -f "$tmpfile" && exec true; }. + qq{ (cat $tmpfile; rm $tmpfile; cat - ) | }. + "($command);"; + } + if($opt::tmux) { + # Wrap command with 'tmux' + $command = $self->tmux_wrap($command); + } + $self->{'wrapped'} = $command; + } + return $self->{'wrapped'}; +} + sub set_sshlogin { my $self = shift; my $sshlogin = shift; @@ -5382,32 +5472,22 @@ sub sshlogin { sub sshlogin_wrap { # Wrap the command with the commands needed to run remotely - # Uses: - # @Global::cat_partials - # $Global::envvar + # Returns: + # $self->{'sshlogin_wrap'} = command wrapped with ssh+transfer commands my $self = shift; + my $command = shift; if(not defined $self->{'sshlogin_wrap'}) { my $sshlogin = $self->sshlogin(); my $sshcmd = $sshlogin->sshcommand(); my $serverlogin = $sshlogin->serverlogin(); - my $next_command_line = $Global::envvar.$self->replaced(); my ($pre,$post,$cleanup)=("","",""); if($serverlogin eq ":") { - if(@Global::cat_partials) { - # Prepend: - # < /tmp/foo perl -e 'while(@ARGV) { sysseek(STDIN,shift,0) || die; $left = shift; while($read = sysread(STDIN,$buf, ($left > 32768 ? 32768 : $left))){ $left -= $read; syswrite(STDOUT,$buf); } }' 0 0 0 11 | - $self->{'sshlogin_wrap'} = (shift @Global::cat_partials). "|". - "(". $next_command_line. ")"; - } else { - $self->{'sshlogin_wrap'} = $next_command_line; - } + # No transfer neeeded + $self->{'sshlogin_wrap'} = $command; } else { # --transfer $pre .= $self->sshtransfer(); - if(@Global::cat_partials) { - $pre .= (shift @Global::cat_partials)."|"; - } # --return $post .= $self->sshreturn(); # --cleanup @@ -5474,7 +5554,7 @@ sub sshlogin_wrap { . "$sshcmd $ssh_options $serverlogin $parallel_env " . $remote_pre # . ::shell_quote_scalar($signal_script . ::shell_quote_scalar($next_command_line)) - . ::shell_quote_scalar($next_command_line) + . ::shell_quote_scalar($command) . ";" . $post); } @@ -5692,7 +5772,7 @@ sub start { # job-object or undef if job not to run my $job = shift; # Get the shell command to be executed (possibly with ssh infront). - my $command = $job->sshlogin_wrap(); + my $command = $job->wrapped(); if($Global::interactive or $Global::stderr_verbose) { if($Global::interactive) { @@ -5733,21 +5813,6 @@ sub start { $job->seq(), "): $command\n"); if($opt::pipe) { my ($stdin_fh); - # Wrap command with end-of-file detector, - # so we do not spawn a program if there is no input. - # Exit value: - # empty input = true - # some input = exit val from command - my ($dummy_fh, $tmpfile) = ::tmpfile(SUFFIX => ".chr"); - $command = qq{ - sh -c 'dd bs=1 count=1 of=$tmpfile 2>/dev/null'; - test \! -s "$tmpfile" && rm -f "$tmpfile" && exec true; - (cat $tmpfile; rm $tmpfile; cat - ) | } . - "($command);"; - if($opt::tmux) { - $command = $job->tmux_wrap($command); - } - # The eval is needed to catch exception from open3 eval { $pid = ::open3($stdin_fh, ">&OUT", ">&ERR", $Global::shell, "-c", $command) || @@ -5760,9 +5825,6 @@ sub start { # Give STDIN to the first job if using -a (but only if running # locally - otherwise CTRL-C does not work for other jobs Bug#36585) *IN = *STDIN; - if($opt::tmux) { - $command = $job->tmux_wrap($command); - } # The eval is needed to catch exception from open3 eval { $pid = ::open3("<&IN", ">&OUT", ">&ERR", $Global::shell, "-c", $command) || @@ -5776,9 +5838,6 @@ sub start { open(my $devtty_fh, "<", "/dev/tty")) { # Give /dev/tty to the command if no one else is using it *IN = $devtty_fh; - if($opt::tmux) { - $command = $job->tmux_wrap($command); - } # The eval is needed to catch exception from open3 eval { $pid = ::open3("<&IN", ">&OUT", ">&ERR", $Global::shell, "-c", $command) || @@ -5788,9 +5847,6 @@ sub start { 1; }; } else { - if($opt::tmux) { - $command = $job->tmux_wrap($command); - } # The eval is needed to catch exception from open3 eval { $pid = ::open3(::gensym, ">&OUT", ">&ERR", $Global::shell, "-c", $command) || @@ -5830,7 +5886,7 @@ sub tmux_wrap { close $fh; unlink $tmpfile; my $visual_command = $self->replaced(); - my $title = ::undef_as_empty($self->{'commandline'}->replace_placeholders(["\257<\257>"],0,0)).""; + my $title = $visual_command; # ; causes problems # ascii 194-245 annoys tmux $title =~ tr/[\011-\016;\302-\365]//d; @@ -5846,11 +5902,12 @@ sub tmux_wrap { return "mkfifo $tmpfile; $tmux ". # Run in tmux ::shell_quote_scalar( - "(".$actual_command.');(echo $?$status;echo 255) >'.$tmpfile.";". + "(".$actual_command.');(echo $?$status;echo 255) >'.$tmpfile."&". "echo ".::shell_quote_scalar($visual_command).";". "echo \007Job finished at: `date`;sleep 10"). # Run outside tmux - "; exit `perl -ne 'unlink $ARGV; 1..1 and print' $tmpfile;rm $tmpfile` "; + # Read the first line from the fifo and use that as status code + "; exit `perl -ne 'unlink \$ARGV; 1..1 and print' $tmpfile` "; } sub is_already_in_results { @@ -5924,7 +5981,7 @@ sub print { $Global::grouped or return; # Check for disk full exit_if_disk_full(); - my $command = $self->sshlogin_wrap(); + my $command = $self->wrapped(); if(($opt::dryrun or $Global::verbose) and $Global::grouped and @@ -6256,7 +6313,7 @@ sub populate { my $max_len = $Global::minimal_command_line_length || Limits::Command::max_length(); if($opt::cat or $opt::fifo) { - # Get a tempfile name + # Generate a tempfile name that will be used as {} my($outfh,$name) = ::tmpfile(SUFFIX => ".pip"); close $outfh; # Unlink is needed if: ssh otheruser@localhost @@ -6484,6 +6541,8 @@ sub header_indexes_sorted { } sub len { + # Uses: + # $opt::shellquote # The length of the command line with args substituted my $self = shift; my $len = 0; @@ -6546,63 +6605,18 @@ sub replaced { # Uses: # $Global::noquote # $Global::quoting - # $opt::cat - # $opt::fifo - # $opt::nice - # $opt::shellquote # Returns: # $replaced = command with place holders replaced and prepended my $self = shift; if(not defined $self->{'replaced'}) { # Don't quote arguments if the input is the full command line my $quote_arg = $Global::noquote ? 0 : not $Global::quoting; - my $cmdstring = $self->replace_placeholders($self->{'command'},$Global::quoting,$quote_arg); - if (length($cmdstring) != $self->len()) { - ::debug("length", length $cmdstring, " != ", $self->len(), " ", $cmdstring, "\n"); + $self->{'replaced'} = $self->replace_placeholders($self->{'command'},$Global::quoting,$quote_arg); + my $len = length $self->{'replaced'}; + if ($len != $self->len()) { + ::debug("length", $len, " != ", $self->len(), " ", $self->{'replaced'}, "\n"); } else { - ::debug("length", length $cmdstring, " == ", $self->len(), " ", $cmdstring, "\n"); - } - if($opt::cat) { - # Prepend 'cat > {};' - # Append '_EXIT=$?;(rm {};exit $_EXIT)' - $self->{'replaced'} = - $self->replace_placeholders(["cat > \257<\257>; ", $cmdstring, - "; _EXIT=\$?; rm \257<\257>; exit \$_EXIT"], - 0,0); - } elsif($opt::fifo) { - # Prepend 'mkfifo {}; (' - # Append ') & _PID=$!; cat > {}; wait $_PID; _EXIT=$?;(rm {};exit $_EXIT)' - $self->{'replaced'} = - $self->replace_placeholders(["mkfifo \257<\257>; (", - $cmdstring, - ") & _PID=\$!; cat > \257<\257>; ", - "wait \$_PID; _EXIT=\$?; ", - "rm \257<\257>; exit \$_EXIT"], - 0,0); - } else { - $self->{'replaced'} = $cmdstring; - } - if($self->{'replaced'} =~ /^\s*(-\S+)/) { - # Is this really a command in $PATH starting with '-'? - my $cmd = $1; - if(not ::which($cmd)) { - ::error("Command ($cmd) starts with '-'. Is this a wrong option?\n"); - ::wait_and_exit(255); - } - } - if($opt::nice) { - # Prepend \nice -n19 $SHELL -c - # and quote - # \ before nice is needed to avoid tcsh's built-in - $self->{'replaced'} = '\nice'. " -n". $opt::nice. " ". - $Global::shell. " -c ". - ::shell_quote_scalar($self->{'replaced'}); - } - if($opt::shellquote) { - # Prepend echo - # and quote twice - $self->{'replaced'} = "echo " . - ::shell_quote_scalar(::shell_quote_scalar($self->{'replaced'})); + ::debug("length", $len, " == ", $self->len(), " ", $self->{'replaced'}, "\n"); } } return $self->{'replaced'}; @@ -6761,6 +6775,15 @@ sub new { my @unget = (); my ($count,%replacecount,$posrpl,$perlexpr,%len); my @command = @$commandref; + # If the first command start with '-' it is probably an option + if($command[0] =~ /^\s*(-\S+)/) { + # Is this really a command in $PATH starting with '-'? + my $cmd = $1; + if(not ::which($cmd)) { + ::error("Command ($cmd) starts with '-'. Is this a wrong option?\n"); + ::wait_and_exit(255); + } + } # Replace replacement strings with {= perl expr =} # Protect matching inside {= perl expr =} # by replacing {= and =} with \257< and \257> diff --git a/src/parallel.pod b/src/parallel.pod index afd5b325..d1eb0b6c 100644 --- a/src/parallel.pod +++ b/src/parallel.pod @@ -160,7 +160,7 @@ B<--basenameextensionreplace>. To understand replacement strings see B<{}>. -=item B<{#}> (alpha testing) +=item B<{#}> (beta testing) Sequence number of the job to run. This replacement string will be replaced by the sequence number of the job being run. It contains the @@ -171,7 +171,7 @@ The replacement string B<{#}> can be changed with B<--seqreplace>. To understand replacement strings see B<{}>. -=item B<{%}> (alpha testing) +=item B<{%}> (beta testing) Job slot number. This replacement string will be replaced by the job's slot number between 1 and number of jobs to run in parallel. There @@ -556,7 +556,7 @@ If I is omitted, there is no end of file string. If neither B<-E> nor B<-e> is used, no end of file string is used. -=item B<--env> I (alpha testing) +=item B<--env> I (beta testing) Copy environment variable I. This will copy I to the environment that the command is run in. This is especially useful for @@ -937,7 +937,7 @@ This is useful for scripts that depend on features only available from a certain version of GNU B. -=item B<--nonall> (beta testing) +=item B<--nonall> B<--onall> with no arguments. Run the command on all computers given with B<--sshlogin> but take no arguments. GNU B will log @@ -948,7 +948,7 @@ This is useful for running the same command (e.g. uptime) on a list of servers. -=item B<--onall> (beta testing) +=item B<--onall> Run all the jobs on all computers given with B<--sshlogin>. GNU B will log into B<--jobs> number of computers in parallel @@ -999,7 +999,7 @@ B<--files> is often used with B<--pipe>. See also: B<--recstart>, B<--recend>, B<--fifo>, B<--cat>, B<--pipepart>. -=item B<--pipepart> (beta testing) +=item B<--pipepart> Pipe parts of a physical file. B<--pipepart> works similar to B<--pipe>, but is much faster. It has a few limitations: @@ -1587,9 +1587,9 @@ B<--sshlogin> is often used with B<--transfer>, B<--return>, B<--cleanup>, and B<--trc>. -=item B<--sshloginfile> I (beta testing) +=item B<--sshloginfile> I -=item B<--slf> I (beta testing) +=item B<--slf> I File with sshlogins. The file consists of sshlogins on separate lines. Empty lines and lines starting with '#' are ignored. Example: @@ -3198,7 +3198,7 @@ by: B. This only works on the local computer. -=item $PARALLEL_SHELL (alpha testing) +=item $PARALLEL_SHELL (beta testing) Use this shell the shell for the commands run by GNU Parallel: diff --git a/src/sql b/src/sql index 4ba5421d..870b9ef8 100755 --- a/src/sql +++ b/src/sql @@ -566,7 +566,7 @@ $Global::Initfile && unlink $Global::Initfile; exit ($err); sub parse_options { - $Global::version = 20141022; + $Global::version = 20141023; $Global::progname = 'sql'; # This must be done first as this may exec myself diff --git a/testsuite/tests-to-run/test13.sh b/testsuite/tests-to-run/test13.sh index 6ef1fd6c..c58df869 100755 --- a/testsuite/tests-to-run/test13.sh +++ b/testsuite/tests-to-run/test13.sh @@ -1,7 +1,7 @@ #!/bin/bash echo '### Test -k' -ulimit -n 50 +ulimit -n 70 (echo "sleep 3; echo begin"; seq 1 30 | parallel -kq echo "sleep 1; echo {}"; echo "echo end") \ | stdout parallel -k -j0 diff --git a/testsuite/wanted-results/parallel-local13 b/testsuite/wanted-results/parallel-local13 index 85afc158..cb0281e0 100644 --- a/testsuite/wanted-results/parallel-local13 +++ b/testsuite/wanted-results/parallel-local13 @@ -1,6 +1,9 @@ ### Tests from xargs +parallel: Warning: Only enough file handles to run 248 jobs in parallel. +Running 'parallel -j0 -N248 --pipe parallel -j0' or raising ulimit -n or /etc/security/limits.conf may help. echo '### -0 -n3 echo < files0.xi' ### -0 -n3 echo < files0.xi +parallel: Warning: No more file handles. Raising ulimit -n or /etc/security/limits.conf may help. stdout xargs -0 -n3 echo < files0.xi /src/gnu/autoconf-1.11 /src/gnu/autoconf-1.11/README /src/gnu/autoconf-1.11/Makefile.in /src/gnu/autoconf-1.11/INSTALL /src/gnu/autoconf-1.11/NEWS /src/gnu/autoconf-1.11/COPYING diff --git a/testsuite/wanted-results/test19 b/testsuite/wanted-results/test19 index 80177bfa..7e7a76d2 100644 --- a/testsuite/wanted-results/test19 +++ b/testsuite/wanted-results/test19 @@ -77,35 +77,35 @@ OK Input for ssh parallel@parallel-server1 mkdir -p ./. -l parallel parallel-server1 rsync --server -lDrRze.iLsfx . ./. --tt -oLogLevel=quiet parallel@parallel-server1 eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ 2\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=2\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; tty >/dev/null && stty isig -onlcr -echo;cat tmp/parallel.file.' -'newline2 > tmp/parallel.file.' -'newline2.out;cat tmp/parallel.file.' -'newline2 > tmp/parallel.file.' -'newline2.out2 --l parallel parallel-server1 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' -'newline2.out --l parallel parallel-server1 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' -'newline2.out2 -parallel@parallel-server1 (rm -f ./tmp/parallel.file.' -'newline2; rmdir ./tmp/ ./ 2>/dev/null;) -parallel@parallel-server1 (rm -f ./tmp/parallel.file.' -'newline2.out; rmdir ./tmp/ ./ 2>/dev/null;) -parallel@parallel-server1 (rm -f ./tmp/parallel.file.' -'newline2.out2; rmdir ./tmp/ ./ 2>/dev/null;) -parallel@parallel-server2 mkdir -p ./. --l parallel parallel-server2 rsync --server -lDrRze.iLsfx . ./. --tt -oLogLevel=quiet parallel@parallel-server2 eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ 1\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=1\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; tty >/dev/null && stty isig -onlcr -echo;cat tmp/parallel.file.' +-tt -oLogLevel=quiet parallel@parallel-server1 eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ 1\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=1\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; tty >/dev/null && stty isig -onlcr -echo;cat tmp/parallel.file.' 'newline1 > tmp/parallel.file.' 'newline1.out;cat tmp/parallel.file.' 'newline1 > tmp/parallel.file.' 'newline1.out2 --l parallel parallel-server2 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' +-l parallel parallel-server1 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' 'newline1.out --l parallel parallel-server2 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' +-l parallel parallel-server1 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' 'newline1.out2 -parallel@parallel-server2 (rm -f ./tmp/parallel.file.' +parallel@parallel-server1 (rm -f ./tmp/parallel.file.' 'newline1; rmdir ./tmp/ ./ 2>/dev/null;) -parallel@parallel-server2 (rm -f ./tmp/parallel.file.' +parallel@parallel-server1 (rm -f ./tmp/parallel.file.' 'newline1.out; rmdir ./tmp/ ./ 2>/dev/null;) -parallel@parallel-server2 (rm -f ./tmp/parallel.file.' +parallel@parallel-server1 (rm -f ./tmp/parallel.file.' 'newline1.out2; rmdir ./tmp/ ./ 2>/dev/null;) +parallel@parallel-server2 mkdir -p ./. +-l parallel parallel-server2 rsync --server -lDrRze.iLsfx . ./. +-tt -oLogLevel=quiet parallel@parallel-server2 eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ 2\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=2\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; tty >/dev/null && stty isig -onlcr -echo;cat tmp/parallel.file.' +'newline2 > tmp/parallel.file.' +'newline2.out;cat tmp/parallel.file.' +'newline2 > tmp/parallel.file.' +'newline2.out2 +-l parallel parallel-server2 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' +'newline2.out +-l parallel parallel-server2 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' +'newline2.out2 +parallel@parallel-server2 (rm -f ./tmp/parallel.file.' +'newline2; rmdir ./tmp/ ./ 2>/dev/null;) +parallel@parallel-server2 (rm -f ./tmp/parallel.file.' +'newline2.out; rmdir ./tmp/ ./ 2>/dev/null;) +parallel@parallel-server2 (rm -f ./tmp/parallel.file.' +'newline2.out2; rmdir ./tmp/ ./ 2>/dev/null;)