From 11a05ca1a3be95160306b1dd0aea73155899ddec Mon Sep 17 00:00:00 2001 From: Ole Tange Date: Tue, 30 Dec 2014 00:31:02 +0100 Subject: [PATCH] parallel: Fixed bug #42493: --sshlogin does not send stderr to stderr. --- doc/boxplot-runtime | 2 +- src/parallel | 132 +++++++++++++------ testsuite/Makefile | 4 +- testsuite/wanted-results/parallel-freebsd | 2 - testsuite/wanted-results/parallel-local-ssh2 | 4 +- testsuite/wanted-results/test15 | 2 +- testsuite/wanted-results/test19 | 20 +-- testsuite/wanted-results/test37 | 2 +- testsuite/wanted-results/test61 | 8 +- 9 files changed, 113 insertions(+), 63 deletions(-) diff --git a/doc/boxplot-runtime b/doc/boxplot-runtime index b1cace2d..142995ef 100644 --- a/doc/boxplot-runtime +++ b/doc/boxplot-runtime @@ -43,7 +43,7 @@ measure() { Rscript - <<_ jl<-read.csv("/tmp/joblog.csv",sep="\t"); - jl\$Command <- as.factor(substr(jl\$Command, 13, nchar(as.character(jl\$Command))-5)) + jl\$Command <- as.factor(substr(jl\$Command, 12, nchar(as.character(jl\$Command))-5)) pdf("/tmp/boxplot.pdf"); par(cex.axis=0.5); boxplot(JobRuntime/$INNER*1000~Command,data=jl,las=2,outline=F, diff --git a/src/parallel b/src/parallel index cb945cfd..57bd913d 100755 --- a/src/parallel +++ b/src/parallel @@ -295,6 +295,7 @@ sub spreadstdin { # $Global::start_no_new_jobs # $opt::roundrobin # %Global::running + # Returns: N/A my $buf = ""; my ($recstart,$recend) = recstartrecend(); @@ -476,6 +477,8 @@ sub nindex { # $endpos = end position of $block # Uses: # %Global::running + # Returns: + # $something_written = amount of bytes written my ($header_ref,$block_ref,$recstart,$recend,$endpos) = @_; my $something_written = 0; my $block_passed = 0; @@ -952,7 +955,7 @@ sub parse_options { sub init_globals { # Defaults: - $Global::version = 20141225; + $Global::version = 20141229; $Global::progname = 'parallel'; $Global::infinity = 2**31; $Global::debug = 0; @@ -1107,8 +1110,10 @@ sub parse_env_var { # Bash functions must be parsed to export them remotely # Pre-shellshock style bash function: # myfunc=() {... - # Post-shellshock style bash function: + # Post-shellshock style bash function (v1): # BASH_FUNC_myfunc()=() {... + # Post-shellshock style bash function (v2): + # BASH_FUNC_myfunc%%=() {... # # Uses: # $Global::envvar = eval string that will set variables in both bash and csh @@ -1143,7 +1148,7 @@ sub parse_env_var { } # Duplicate vars as BASH functions to include post-shellshock functions. # So --env myfunc should also look for BASH_FUNC_myfunc() - @vars = map { $_, "BASH_FUNC_$_()" } @vars; + @vars = map { $_, "BASH_FUNC_$_()", "BASH_FUNC_$_%%" } @vars; # Keep only defined variables @vars = grep { defined($ENV{$_}) } @vars; # Pre-shellshock style bash function: @@ -1152,6 +1157,8 @@ sub parse_env_var { # Post-shellshock style bash function: # BASH_FUNC_myfunc()=() { echo myfunc # } + # BASH_FUNC_myfunc%%=() { echo myfunc + # } my @bash_functions = grep { substr($ENV{$_},0,4) eq "() {" } @vars; my @non_functions = grep { substr($ENV{$_},0,4) ne "() {" } @vars; if(@bash_functions) { @@ -1162,9 +1169,9 @@ sub parse_env_var { } # Pre-shellschock names are without () - my @bash_pre_shellshock = grep { not /\(\)/ } @bash_functions; + my @bash_pre_shellshock = grep { not /\(\)|%%/ } @bash_functions; # Post-shellschock names are with () - my @bash_post_shellshock = grep { /\(\)/ } @bash_functions; + my @bash_post_shellshock = grep { /\(\)|%%/ } @bash_functions; my @qcsh = (map { my $a=$_; "setenv $a " . env_quote($ENV{$a}) } grep { not /^parallel_bash_environment$/ } @non_functions); @@ -1172,14 +1179,14 @@ sub parse_env_var { @non_functions, @bash_pre_shellshock); push @qbash, map { my $a=$_; "eval $a\"\$$a\"" } @bash_pre_shellshock; - push @qbash, map { /BASH_FUNC_(.*)\(\)/; "$1 $ENV{$_}" } @bash_post_shellshock; + push @qbash, map { /BASH_FUNC_(.*)(\(\)|%%)/; "$1 $ENV{$_}" } @bash_post_shellshock; #ssh -tt -oLogLevel=quiet lo 'eval `echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;echo\ \$SHELL\ \|\ grep\ \"/t\\\{0,1\\\}csh\"\ \>\ /dev/null\ \&\&\ setenv\ BASH_FUNC_myfunc\ \\\(\\\)\\\ \\\{\\\ \\\ echo\\\ a\"' #'\"\\\}\ \|\|\ myfunc\(\)\ \{\ \ echo\ a' #'\}\ \;myfunc\ 1; # Check if any variables contain \n - if(my @v = map { s/BASH_FUNC_(.*)\(\)/$1/; $_ } grep { $ENV{$_}=~/\n/ } @vars) { + if(my @v = map { s/BASH_FUNC_(.*)(\(\)|%%)/$1/; $_ } grep { $ENV{$_}=~/\n/ } @vars) { # \n is bad for csh and will cause it to fail. $Global::envwarn = ::shell_quote_scalar(q{echo $SHELL | egrep "/t?csh" > /dev/null && echo CSH/TCSH DO NOT SUPPORT newlines IN VARIABLES/FUNCTIONS. Unset }."@v".q{ && exec false;}."\n\n") . $Global::envwarn; } @@ -4880,7 +4887,7 @@ sub no_of_cpus_qnx { # Returns: # Number of physical CPUs on QNX # undef if not QNX - # BUG: It is now known how to calculate this. + # BUG: It is not known how to calculate this. my $no_of_cpus = 0; return $no_of_cpus; } @@ -4889,7 +4896,7 @@ sub no_of_cores_qnx { # Returns: # Number of CPU cores on QNX # undef if not QNX - # BUG: It is now known how to calculate this. + # BUG: It is not known how to calculate this. my $no_of_cores = 0; return $no_of_cores; } @@ -5221,10 +5228,10 @@ sub new { return bless { 'commandline' => $commandlineref, # CommandLine object 'workdir' => undef, # --workdir - 'stdin' => undef, # filehandle for stdin (used for --pipe) + # filehandle for stdin (used for --pipe) # filename for writing stdout to (used for --files) - 'remaining' => "", # remaining data not sent to stdin (used for --pipe) - 'datawritten' => 0, # amount of data sent via stdin (used for --pipe) + # remaining data not sent to stdin (used for --pipe) + # amount of data sent via stdin (used for --pipe) 'transfersize' => 0, # size of files using --transfer 'returnsize' => 0, # size of files using --return 'pid' => undef, @@ -5540,15 +5547,9 @@ sub non_block_write { my $self = shift; my $something_written = 0; use POSIX qw(:errno_h); -# use Fcntl; -# my $flags = ''; + # for loop used to avoid copying substr: $buf will be an alias for the substr for my $buf (substr($self->{'stdin_buffer'},$self->{'stdin_buffer_pos'})) { my $in = $self->fh(0,"w"); -# fcntl($in, F_GETFL, $flags) -# or die "Couldn't get flags for HANDLE : $!\n"; -# $flags |= O_NONBLOCK; -# fcntl($in, F_SETFL, $flags) -# or die "Couldn't set flags for HANDLE: $!\n"; my $rv = syswrite($in, $buf); if (!defined($rv) && $! == EAGAIN) { # would block @@ -5875,6 +5876,49 @@ sub sshlogin_wrap { # Wrap the command with the commands needed to run remotely # Returns: # $self->{'sshlogin_wrap'} = command wrapped with ssh+transfer commands + sub monitor_parent_sshd_script { + # This script is to solve the problem of + # * not mixing STDERR and STDOUT + # * terminating with ctrl-c + # If its parent is ssh: all good + # If its parent is init(1): ssh died, so kill children + my $monitor_parent_sshd_script; + if(not $monitor_parent_sshd_script) { + $monitor_parent_sshd_script = + # This will be packed in ', so only use " + q{ + # If packed as hex, unpack + # if($ARGV[0] =~ s/^0x//) { + # $ARGV[0] =~ s/(..)/chr(hex $1)/ge; + #} + $SIG{CHLD} = sub { $done = 1; }; + $pid = fork; + unless($pid) { + # Make own process group to be able to kill HUP it later + setpgrp; + exec $ENV{SHELL}, "-c", @ARGV; + die "exec: $!\n"; + } + do { + # Parent is not init (ppid=1), so sshd is alive + # Exponential sleep up to 1 sec + $s = $s < 1 ? 0.001 + $s * 1.03 : $s; + select(undef, undef, undef, $s); + } until ($done || getppid == 1); + # Kill HUP the process group if job not done + kill(SIGHUP, -${pid}) unless $done; + wait; + exit ($?&127 ? 128+($?&127) : 1+$?>>8) + }; + $monitor_parent_sshd_script =~ s/#.*//mg; + $monitor_parent_sshd_script =~ s/\s//mg; + } + return $monitor_parent_sshd_script; + } + #sub hex_pack { + #return unpack("H*","@_"); + #} + my $self = shift; my $command = shift; if(not defined $self->{'sshlogin_wrap'}) { @@ -5913,17 +5957,16 @@ sub sshlogin_wrap { if(($opt::pipe or $opt::pipepart) and $opt::ctrlc or not ($opt::pipe or $opt::pipepart) and not $opt::noctrlc) { - # TODO Determine if this is needed # Propagating CTRL-C to kill remote jobs requires # remote jobs to be run with a terminal. - $ssh_options = "-tt -oLogLevel=quiet"; -# $ssh_options = ""; +# $ssh_options = "-tt -oLogLevel=quiet"; + $ssh_options = ""; # tty - check if we have a tty. # stty: # -onlcr - make output 8-bit clean # isig - pass CTRL-C as signal # -echo - do not echo input - $remote_pre .= ::shell_quote_scalar('tty >/dev/null && stty isig -onlcr -echo;'); +# $remote_pre .= ::shell_quote_scalar('tty >/dev/null && stty isig -onlcr -echo;'); } if($opt::workdir) { my $wd = ::shell_quote_file($self->workdir()); @@ -5933,34 +5976,43 @@ sub sshlogin_wrap { # but that fails on tcsh ::shell_quote_scalar(qq{ || exec false;}); } - # This script is to solve the problem of - # * not mixing STDERR and STDOUT - # * terminating with ctrl-c + my $signal_script = "exec perl -e '".monitor_parent_sshd_script()."' "; + # TODO clean this up + # TODO Maybe env vars should be set in the perl script # It works on Linux but not Solaris # Finishes on Solaris, but wrong exit code: # $SIG{CHLD} = sub {exit ($?&127 ? 128+($?&127) : 1+$?>>8)}; # Hangs on Solaris, but correct exit code on Linux: # $SIG{CHLD} = sub { $done = 1 }; # $p->poll; - my $signal_script = "perl -e '". - q{ - use IO::Poll; - $SIG{CHLD} = sub { $done = 1 }; - $p = IO::Poll->new; - $p->mask(STDOUT, POLLHUP); - $pid=fork; unless($pid) {setpgrp; exec $ENV{SHELL}, "-c", @ARGV; die "exec: $!\n"} - $p->poll; - kill SIGHUP, -${pid} unless $done; - wait; exit ($?&127 ? 128+($?&127) : 1+$?>>8) - } . "' "; - $signal_script =~ s/\s+/ /g; + + # $SIG{CHLD} = sub { $done = 1; ($^O eq "solaris") && exit 0 }; + # $SIG{CHLD} = sub { $done = 1; (1) && exit ($?&127 ? 128+($?&127) : 1+$?>>8); }; + # $SIG{CHLD} = sub { $done = 1; exit ($?&127 ? 128+($?&127) : 1+$?>>8); }; + # -> Linux: "" +script + # -> Solaris: -tt -script + # --ctrl-c => -tt +# q{ +# ($^O eq "solaris") && exec $ENV{SHELL}, "-c", @ARGV; +# $|=1; +# use IO::Poll; +# $SIG{CHLD} = sub {$done = 1; }; +# $pid=fork; unless($pid) {setpgrp; exec $ENV{SHELL}, "-c", @ARGV; die "exec: $!\n"} +# $p = IO::Poll->new; +# $p->mask(STDOUT, POLLHUP); +# $p->poll; +# kill SIGHUP, -${pid} unless $done; +# wait; exit ($?&127 ? 128+($?&127) : 1+$?>>8) +# } . "' "; +# $signal_script =~ s/\s+/ /g; $self->{'sshlogin_wrap'} = ($pre . "$sshcmd $ssh_options $serverlogin $parallel_env " . $remote_pre -# . ::shell_quote_scalar($signal_script . ::shell_quote_scalar($command)) - . ::shell_quote_scalar($command) + . ::shell_quote_scalar($signal_script . ::shell_quote_scalar($command)) +# . ::shell_quote_scalar($signal_script . hex_pack($command)) +# . ::shell_quote_scalar($command) . ";" . $post); } diff --git a/testsuite/Makefile b/testsuite/Makefile index d4d46fe3..5add6ec6 100644 --- a/testsuite/Makefile +++ b/testsuite/Makefile @@ -80,5 +80,5 @@ portable: timings: tests-to-run/* ../src/parallel ls tests-to-run/*.sh | parallel echo /usr/bin/time -f %e bash >/tmp/timing.script stdout bash -x /tmp/timing.script | tee /tmp/timing.out - echo usr.bin.time_END >>/tmp/timing.out - perl -ne '/usr.bin.time/ and do { print $$last.$$h; $$h=$$_ }; chomp; $$last = $$_' /tmp/timing.out | sort -n >timings + echo + .usr.bin.time_END >>/tmp/timing.out + perl -ne '/\+ .usr.bin.time/ and do { print $$last.$$h; $$h=$$_ }; chomp; s/.*\0//;$$last = $$_' /tmp/timing.out |sort -n >timings diff --git a/testsuite/wanted-results/parallel-freebsd b/testsuite/wanted-results/parallel-freebsd index de71325b..6f011add 100644 --- a/testsuite/wanted-results/parallel-freebsd +++ b/testsuite/wanted-results/parallel-freebsd @@ -59,9 +59,7 @@ bash -c 'echo bug \#43358: shellshock breaks exporting functions using --env _; bug #43358: shellshock breaks exporting functions using --env _ Non-shellshock-hardened to non-shellshock-hardened Function non-shellshock-hardened -tcgetattr: Inappropriate ioctl for device bash -c 'echo bug \#43358: shellshock breaks exporting functions using --env _; echo Non-shellshock-hardened to shellshock-hardened; funky() { echo Function $1; }; export -f funky; parallel --env funky -S parallel@192.168.1.72 funky ::: shellshock-hardened' bug #43358: shellshock breaks exporting functions using --env _ Non-shellshock-hardened to shellshock-hardened Function shellshock-hardened -tcgetattr: Inappropriate ioctl for device diff --git a/testsuite/wanted-results/parallel-local-ssh2 b/testsuite/wanted-results/parallel-local-ssh2 index d6756b7f..f1621547 100644 --- a/testsuite/wanted-results/parallel-local-ssh2 +++ b/testsuite/wanted-results/parallel-local-ssh2 @@ -29,8 +29,8 @@ Exit code 1 echo '### bug #42725: csh with \n in variables' ### bug #42725: csh with \n in variables not_csh() { echo This is not csh/tcsh; }; export -f not_csh; parallel --env not_csh -S csh@lo not_csh ::: 1; parallel --env not_csh -S tcsh@lo not_csh ::: 1; parallel --env not_csh -S parallel@lo not_csh ::: 1 -CSH/TCSH DO NOT SUPPORT newlines IN VARIABLES/FUNCTIONS. Unset not_csh -CSH/TCSH DO NOT SUPPORT newlines IN VARIABLES/FUNCTIONS. Unset not_csh +CSH/TCSH DO NOT SUPPORT newlines IN VARIABLES/FUNCTIONS. Unset not_csh +CSH/TCSH DO NOT SUPPORT newlines IN VARIABLES/FUNCTIONS. Unset not_csh This is not csh/tcsh Badly placed ()'s. }: Command not found. diff --git a/testsuite/wanted-results/test15 b/testsuite/wanted-results/test15 index aecb222f..c060e764 100644 --- a/testsuite/wanted-results/test15 +++ b/testsuite/wanted-results/test15 @@ -754,7 +754,7 @@ args on cmdline \nice -n1 /bin/bash -c PAR=a\ bash\ -c\ \"echo\ \ \\\$PAR\ b\" a b ### Test --nice remote -ssh -tt -oLogLevel=quiet one-server 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;\\nice\ -n1\ /bin/bash\ -c\ PAR=a\\\ bash\\\ -c\\\ \\\"echo\\\ \\\ \\\\\\\$PAR\\\ b\\\"; +ssh one-server 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' exec\ perl\ -e\ \'\$SIG\{CHLD\}=sub\{\$done=1\;\}\;\$pid=fork\;unless\(\$pid\)\{setpgrp\;exec\$ENV\{SHELL\},\"-c\",@ARGV\;die\"exec:\$\!\\n\"\;\}do\{\$s=\$s\<1\?0.001+\$s\*1.03:\$s\;select\(undef,undef,undef,\$s\)\;\}until\(\$done\|\|getppid==1\)\;kill\(SIGHUP,-\$\{pid\}\)unless\$done\;wait\;exit\(\$\?\&127\?128+\(\$\?\&127\):1+\$\?\>\>8\)\'\ \\\\nice\\\ -n1\\\ /bin/bash\\\ -c\\\ PAR=a\\\\\\\ bash\\\\\\\ -c\\\\\\\ \\\\\\\"echo\\\\\\\ \\\\\\\ \\\\\\\\\\\\\\\$PAR\\\\\\\ b\\\\\\\"; a b ### Test distribute arguments at EOF to 2 jobslots 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 diff --git a/testsuite/wanted-results/test19 b/testsuite/wanted-results/test19 index d8cf0b8e..9448ad67 100644 --- a/testsuite/wanted-results/test19 +++ b/testsuite/wanted-results/test19 @@ -77,11 +77,11 @@ 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 X\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=X\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; tty >/dev/null && stty isig -onlcr -echo;cat tmp/parallel.file.' -'newlineX > tmp/parallel.file.' -'newlineX.out;cat tmp/parallel.file.' -'newlineX > tmp/parallel.file.' -'newlineX.out2 +parallel@parallel-server1 eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ X\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=X\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; exec perl -e '$SIG{CHLD}=sub{$done=1;};$pid=fork;unless($pid){setpgrp;exec$ENV{SHELL},"-c",@ARGV;die"exec:$!\n";}do{$s=$s<1?0.001+$s*1.03:$s;select(undef,undef,undef,$s);}until($done||getppid==1);kill(SIGHUP,-${pid})unless$done;wait;exit($?&127?128+($?&127):1+$?>>8)' cat\ tmp/parallel.file.\'' +'\'newlineX\ \>\ tmp/parallel.file.\'' +'\'newlineX.out\;cat\ tmp/parallel.file.\'' +'\'newlineX\ \>\ tmp/parallel.file.\'' +'\'newlineX.out2 -l parallel parallel-server1 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' 'newlineX.out -l parallel parallel-server1 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' @@ -94,11 +94,11 @@ parallel@parallel-server1 (rm -f ./tmp/parallel.file.' 'newlineX.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 X\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=X\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; tty >/dev/null && stty isig -onlcr -echo;cat tmp/parallel.file.' -'newlineX > tmp/parallel.file.' -'newlineX.out;cat tmp/parallel.file.' -'newlineX > tmp/parallel.file.' -'newlineX.out2 +parallel@parallel-server2 eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ X\; setenv PARALLEL_PID 00000 || echo PARALLEL_SEQ=X\;export PARALLEL_SEQ\; PARALLEL_PID=00000\;export PARALLEL_PID` ; exec perl -e '$SIG{CHLD}=sub{$done=1;};$pid=fork;unless($pid){setpgrp;exec$ENV{SHELL},"-c",@ARGV;die"exec:$!\n";}do{$s=$s<1?0.001+$s*1.03:$s;select(undef,undef,undef,$s);}until($done||getppid==1);kill(SIGHUP,-${pid})unless$done;wait;exit($?&127?128+($?&127):1+$?>>8)' cat\ tmp/parallel.file.\'' +'\'newlineX\ \>\ tmp/parallel.file.\'' +'\'newlineX.out\;cat\ tmp/parallel.file.\'' +'\'newlineX\ \>\ tmp/parallel.file.\'' +'\'newlineX.out2 -l parallel parallel-server2 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' 'newlineX.out -l parallel parallel-server2 cd ././tmp; rsync --server --sender -lDrRze.iLsfx . ./parallel.file.' diff --git a/testsuite/wanted-results/test37 b/testsuite/wanted-results/test37 index e5b321bc..ecae584b 100644 --- a/testsuite/wanted-results/test37 +++ b/testsuite/wanted-results/test37 @@ -42,7 +42,7 @@ echo /dev/fd/62 /dev/fd/62 echo foo foo -ssh parallel@redhat9.tange.dk ssh -tt -oLogLevel=quiet centos3.tange.dk 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;perl\ -pe\ \"\\\$a=1\;\ print\ \\\$a\"\ \<\(echo\ foo\); +ssh parallel@redhat9.tange.dk ssh centos3.tange.dk 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' exec\ perl\ -e\ \'\$SIG\{CHLD\}=sub\{\$done=1\;\}\;\$pid=fork\;unless\(\$pid\)\{setpgrp\;exec\$ENV\{SHELL\},\"-c\",@ARGV\;die\"exec:\$\!\\n\"\;\}do\{\$s=\$s\<1\?0.001+\$s\*1.03:\$s\;select\(undef,undef,undef,\$s\)\;\}until\(\$done\|\|getppid==1\)\;kill\(SIGHUP,-\$\{pid\}\)unless\$done\;wait\;exit\(\$\?\&127\?128+\(\$\?\&127\):1+\$\?\>\>8\)\'\ perl\\\ -pe\\\ \\\"\\\\\\\$a=1\\\;\\\ print\\\ \\\\\\\$a\\\"\\\ \\\<\\\(echo\\\ foo\\\); 1foo ### Test quoting of $ in command from profile file perl -pe '$a=1; print $a' <(echo foo) diff --git a/testsuite/wanted-results/test61 b/testsuite/wanted-results/test61 index c68af0d1..0d64ab8b 100644 --- a/testsuite/wanted-results/test61 +++ b/testsuite/wanted-results/test61 @@ -1,15 +1,15 @@ echo '### Test --return of weirdly named file' ### Test --return of weirdly named file stdout parallel --return {} -vv -S parallel\@parallel-server3 echo '>'{} ::: 'aa<${#}" b'; rm 'aa<${#}" b' -ssh -tt -oLogLevel=quiet parallel@parallel-server3 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;echo\ \>aa\\\<\\\$\\\{\\\#\\\}\\\"\\\ b;_EXIT_status=$?; mkdir -p ./.; rsync --protocol 30 --rsync-path=cd\ ././.\;\ rsync -rlDzR -essh parallel@parallel-server3:./aa\\\<\\\$\\\{\\\#\\\}\\\"\\\ b ./.; exit $_EXIT_status; +ssh parallel@parallel-server3 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' exec\ perl\ -e\ \'\$SIG\{CHLD\}=sub\{\$done=1\;\}\;\$pid=fork\;unless\(\$pid\)\{setpgrp\;exec\$ENV\{SHELL\},\"-c\",@ARGV\;die\"exec:\$\!\\n\"\;\}do\{\$s=\$s\<1\?0.001+\$s\*1.03:\$s\;select\(undef,undef,undef,\$s\)\;\}until\(\$done\|\|getppid==1\)\;kill\(SIGHUP,-\$\{pid\}\)unless\$done\;wait\;exit\(\$\?\&127\?128+\(\$\?\&127\):1+\$\?\>\>8\)\'\ echo\\\ \\\>aa\\\\\\\<\\\\\\\$\\\\\\\{\\\\\\\#\\\\\\\}\\\\\\\"\\\\\\\ b;_EXIT_status=$?; mkdir -p ./.; rsync --protocol 30 --rsync-path=cd\ ././.\;\ rsync -rlDzR -essh parallel@parallel-server3:./aa\\\<\\\$\\\{\\\#\\\}\\\"\\\ b ./.; exit $_EXIT_status; echo '### Test if remote login shell is csh' ### Test if remote login shell is csh stdout parallel -k -vv -S csh@localhost 'echo $PARALLEL_PID $PARALLEL_SEQ {}| wc -w' ::: a b c -ssh -tt -oLogLevel=quiet csh@localhost 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;echo\ \$PARALLEL_PID\ \$PARALLEL_SEQ\ a\|\ wc\ -w; +ssh csh@localhost 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' exec\ perl\ -e\ \'\$SIG\{CHLD\}=sub\{\$done=1\;\}\;\$pid=fork\;unless\(\$pid\)\{setpgrp\;exec\$ENV\{SHELL\},\"-c\",@ARGV\;die\"exec:\$\!\\n\"\;\}do\{\$s=\$s\<1\?0.001+\$s\*1.03:\$s\;select\(undef,undef,undef,\$s\)\;\}until\(\$done\|\|getppid==1\)\;kill\(SIGHUP,-\$\{pid\}\)unless\$done\;wait\;exit\(\$\?\&127\?128+\(\$\?\&127\):1+\$\?\>\>8\)\'\ echo\\\ \\\$PARALLEL_PID\\\ \\\$PARALLEL_SEQ\\\ a\\\|\\\ wc\\\ -w; 3 -ssh -tt -oLogLevel=quiet csh@localhost 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;echo\ \$PARALLEL_PID\ \$PARALLEL_SEQ\ b\|\ wc\ -w; +ssh csh@localhost 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' exec\ perl\ -e\ \'\$SIG\{CHLD\}=sub\{\$done=1\;\}\;\$pid=fork\;unless\(\$pid\)\{setpgrp\;exec\$ENV\{SHELL\},\"-c\",@ARGV\;die\"exec:\$\!\\n\"\;\}do\{\$s=\$s\<1\?0.001+\$s\*1.03:\$s\;select\(undef,undef,undef,\$s\)\;\}until\(\$done\|\|getppid==1\)\;kill\(SIGHUP,-\$\{pid\}\)unless\$done\;wait\;exit\(\$\?\&127\?128+\(\$\?\&127\):1+\$\?\>\>8\)\'\ echo\\\ \\\$PARALLEL_PID\\\ \\\$PARALLEL_SEQ\\\ b\\\|\\\ wc\\\ -w; 3 -ssh -tt -oLogLevel=quiet csh@localhost 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' tty\ \>/dev/null\ \&\&\ stty\ isig\ -onlcr\ -echo\;echo\ \$PARALLEL_PID\ \$PARALLEL_SEQ\ c\|\ wc\ -w; +ssh csh@localhost 'eval `echo $SHELL | grep "/t\{0,1\}csh" > /dev/null && echo setenv PARALLEL_SEQ '$PARALLEL_SEQ'\; setenv PARALLEL_PID '$PARALLEL_PID' || echo PARALLEL_SEQ='$PARALLEL_SEQ'\;export PARALLEL_SEQ\; PARALLEL_PID='$PARALLEL_PID'\;export PARALLEL_PID` ;' exec\ perl\ -e\ \'\$SIG\{CHLD\}=sub\{\$done=1\;\}\;\$pid=fork\;unless\(\$pid\)\{setpgrp\;exec\$ENV\{SHELL\},\"-c\",@ARGV\;die\"exec:\$\!\\n\"\;\}do\{\$s=\$s\<1\?0.001+\$s\*1.03:\$s\;select\(undef,undef,undef,\$s\)\;\}until\(\$done\|\|getppid==1\)\;kill\(SIGHUP,-\$\{pid\}\)unless\$done\;wait\;exit\(\$\?\&127\?128+\(\$\?\&127\):1+\$\?\>\>8\)\'\ echo\\\ \\\$PARALLEL_PID\\\ \\\$PARALLEL_SEQ\\\ c\\\|\\\ wc\\\ -w; 3 echo '### Test {} multiple times in different commands' ### Test {} multiple times in different commands