From 6a6a5e4d01bc61b956e31e7ee1cef8607a085e05 Mon Sep 17 00:00:00 2001 From: Ole Tange Date: Mon, 25 May 2015 02:27:30 +0200 Subject: [PATCH] parallel: Specialized shell_quote_scalar for each shell. Newline quoting for csh. Empty argument quoted as ''. Passes testsuite. --- src/parallel | 136 +++++++++++++----- testsuite/tests-to-run/parallel-local-ssh1.sh | 8 +- testsuite/tests-to-run/parallel-local19.sh | 18 +-- testsuite/tests-to-run/parallel-tutorial.sh | 2 + testsuite/wanted-results/parallel-local-3s | 2 +- testsuite/wanted-results/parallel-local-ssh1 | 8 +- testsuite/wanted-results/parallel-local1 | 10 +- testsuite/wanted-results/parallel-local104 | Bin 370 -> 370 bytes testsuite/wanted-results/parallel-local105 | 6 +- testsuite/wanted-results/parallel-local114 | Bin 11571 -> 11572 bytes testsuite/wanted-results/parallel-local13 | 8 +- testsuite/wanted-results/parallel-local19 | 48 +++---- testsuite/wanted-results/parallel-local22 | 2 +- testsuite/wanted-results/parallel-tutorial | 16 +-- 14 files changed, 164 insertions(+), 100 deletions(-) diff --git a/src/parallel b/src/parallel index 7f59e21c..db1abfb4 100755 --- a/src/parallel +++ b/src/parallel @@ -969,7 +969,8 @@ sub parse_options { } if(defined $opt::nonall) { # Append a dummy empty argument - push @ARGV, $Global::arg_sep, ""; + # \0 => nothing (not the empty string) + push @ARGV, $Global::arg_sep, "\0"; } if(defined $opt::tty) { # Defaults for --tty: -j1 -u @@ -1266,7 +1267,9 @@ sub parse_semaphore { ::wait_and_exit(255); } @opt::a = ("/dev/null"); - push(@Global::unget_argv, [Arg->new("")]); + # Append a dummy empty argument + # \0 => nothing (not the empty string) + push(@Global::unget_argv, [Arg->new("\0")]); $Semaphore::timeout = $opt::semaphoretimeout || 0; if(defined $opt::semaphorename) { $Semaphore::name = $opt::semaphorename; @@ -1639,43 +1642,95 @@ sub shell_quote { # @strings = strings to be quoted # Output: # @shell_quoted_strings = string quoted with \ as needed by the shell - my @strings = (@_); - for my $a (@strings) { - $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; - $a =~ s/[\n]/'\n'/g; # filenames with '\n' is quoted using \' - } - return wantarray ? @strings : "@strings"; -} - -sub shell_quote_empty { - # Inputs: - # @strings = strings to be quoted - # Returns: - # @quoted_strings = empty strings quoted as ''. - my @strings = shell_quote(@_); - for my $a (@strings) { - if($a eq "") { - $a = "''"; - } - } - return wantarray ? @strings : "@strings"; + return wantarray ? + (map { shell_quote_scalar($_) } @_) + : (join" ",map { shell_quote_scalar($_) } @_); } sub shell_quote_scalar { - # Quote the string so shell will not expand any special chars + # Quote the string so the shell will not expand any special chars # Inputs: # $string = string to be quoted # Returns: - # $shell_quoted = string quoted with \ as needed by the shell - my $a = $_[0]; - if(defined $a) { - # Solaris sh wants ^ quoted. - # $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; - # This is 1% faster than the above - $a =~ s/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377]/\\$&/go; - $a =~ s/[\n]/'\n'/go; # filenames with '\n' is quoted using \' + # $shell_quoted = string quoted as needed by the shell + + sub shell_quote_scalar_rc { + # Quote for the rc-shell + my $a = $_[0]; + if(defined $a) { + if(($a =~ s/'/''/g) + + + ($a =~ s/[\n\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/'$&'/go)) { + # A string was replaced + # No need to test for "" or \0 + } elsif($a eq "") { + $a = "''"; + } elsif($a eq "\0") { + $a = ""; + } + } + return $a; } - return $a; + + sub shell_quote_scalar_csh { + # Quote for (t)csh + my $a = $_[0]; + if(defined $a) { + # $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; + # This is 1% faster than the above + if(($a =~ s/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\'\202-\377]/\\$&/go) + + + # quote newline in csh as \\\n + ($a =~ s/[\n]/"\\\n"/go)) { + # A string was replaced + # No need to test for "" or \0 + } elsif($a eq "") { + $a = "''"; + } elsif($a eq "\0") { + $a = ""; + } + } + return $a; + } + + sub shell_quote_scalar_default { + # Quote for other shells + my $a = $_[0]; + if(defined $a) { + # zsh wants '=' quoted + # Solaris sh wants ^ quoted. + # $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; + # This is 1% faster than the above + if(($a =~ s/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\'\202-\377]/\\$&/go) + + + # quote newline as '\n' + ($a =~ s/[\n]/'\n'/go)) { + # A string was replaced + # No need to test for "" or \0 + } elsif($a eq "") { + $a = "''"; + } elsif($a eq "\0") { + $a = ""; + } + } + return $a; + } + + # Speed optimization: Choose the correct shell_quote_scalar_* + # and call that directly from now on + no warnings 'redefine'; + if($Global::shell =~ m:(^|/)t?csh$:) { + # (t)csh + *shell_quote_scalar = \&shell_quote_scalar_csh; + } elsif($Global::shell =~ m:(^|/)rc$:) { + # rc-shell + *shell_quote_scalar = \&shell_quote_scalar_rc; + } else { + # other shells + *shell_quote_scalar = \&shell_quote_scalar_default; + } + # The sub is now redefined. Call it + return shell_quote_scalar(@_); } sub shell_quote_file { @@ -2933,7 +2988,7 @@ sub onall { } my ($input_source_fh_ref,@command) = @_; if($Global::quoting) { - @command = shell_quote_empty(@command); + @command = shell_quote(@command); } # Copy all @input_source_fh (-a and :::) into tempfiles @@ -3665,9 +3720,9 @@ sub which { # All shells known to mankind # # ash bash csh dash fdsh fish fizsh ksh ksh93 mksh pdksh - # posh rbash rush rzsh sash sh static-sh tcsh yash zsh + # posh rbash rc rush rzsh sash sh static-sh tcsh yash zsh my @shells = (qw(ash bash csh dash fdsh fish fizsh ksh - ksh93 mksh pdksh posh rbash rush rzsh + ksh93 mksh pdksh posh rbash rc rush rzsh sash sh static-sh tcsh yash zsh -sh -csh), '-sh (sh)' # sh on FreeBSD ); @@ -8638,7 +8693,8 @@ sub get { if(defined $Global::max_number_of_args and $Global::max_number_of_args == 0) { ::debug("run", "Read 1 but return 0 args\n"); - return [Arg->new("")]; + # \0 => nothing (not the empty string) + return [Arg->new("\0")]; } else { return $ret; } @@ -8981,6 +9037,14 @@ sub new { }, ref($class) || $class; } +sub Q { + # Q alias for ::shell_quote_scalar + # Run shell_quote_scalar once to set the reference to the sub + my @a = ::shell_quote_scalar(@_); + *Q = \&::shell_quote_scalar; + return @a; +} + { my %perleval; diff --git a/testsuite/tests-to-run/parallel-local-ssh1.sh b/testsuite/tests-to-run/parallel-local-ssh1.sh index d39377b1..6d044c83 100644 --- a/testsuite/tests-to-run/parallel-local-ssh1.sh +++ b/testsuite/tests-to-run/parallel-local-ssh1.sh @@ -14,13 +14,13 @@ echo '### Can csh propagate a variable containing \n'; echo '### bug #41805: Idea: propagate --env for parallel --number-of-cores' echo '** test_zsh' - FOO=test_zsh parallel --env FOO,HOME -S zsh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_zsh parallel --env FOO,HOME -S zsh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' echo '** test_zsh_filter' - FOO=test_zsh_filter parallel --filter-hosts --env FOO,HOME -S zsh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_zsh_filter parallel --filter-hosts --env FOO,HOME -S zsh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' echo '** test_csh' - FOO=test_csh parallel --env FOO,HOME -S csh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_csh parallel --env FOO,HOME -S csh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' echo '** test_csh_filter' - FOO=test_csh_filter parallel --filter-hosts --env FOO,HOME -S csh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_csh_filter parallel --filter-hosts --env FOO,HOME -S csh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' echo '** bug #41805 done' echo '### Deal with long command lines on remote servers' diff --git a/testsuite/tests-to-run/parallel-local19.sh b/testsuite/tests-to-run/parallel-local19.sh index 0df5463a..8118b1b1 100755 --- a/testsuite/tests-to-run/parallel-local19.sh +++ b/testsuite/tests-to-run/parallel-local19.sh @@ -45,26 +45,26 @@ seq 1 6 | parallel -k printf '{}.gif\\n' | parallel -j1 -km echo a{}b{.}c{.} seq 1 6 | parallel -k printf '{}.gif\\n' | parallel -j1 -kX echo a{}b{.}c{.} echo '### Test -m with 60000 args'; - seq 1 60000 | perl -pe 's/$/.gif\n/' | + seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -km echo a{}b{.}c{.} | tee >(wc) >(md5sum) >/dev/null; wait echo '### Test -X with 60000 args'; - seq 1 60000 | perl -pe 's/$/.gif\n/' | + seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.} | tee >(wc) >(md5sum) >/dev/null; wait echo '### Test -X with 60000 args and 5 expansions' -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.}{.}{} | wc -l -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.}{.} | wc -l -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.} | wc -l -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c | wc -l -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b | wc -l +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.}{.}{} | wc -l +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.}{.} | wc -l +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.} | wc -l +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c | wc -l +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b | wc -l echo '### Test {.} does not repeat more than {}' -seq 1 15 | perl -pe 's/$/.gif\n/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.} -seq 1 15 | perl -pe 's/$/.gif\n/' | parallel -j1 -s 80 -km echo a{}b{.}c{.} +seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.} +seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -km echo a{}b{.}c{.} seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.} seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -km echo a{}b{.}c{.} diff --git a/testsuite/tests-to-run/parallel-tutorial.sh b/testsuite/tests-to-run/parallel-tutorial.sh index 99f74c15..393b2ed8 100644 --- a/testsuite/tests-to-run/parallel-tutorial.sh +++ b/testsuite/tests-to-run/parallel-tutorial.sh @@ -57,6 +57,8 @@ perl -ne '$/="\n\n"; /^Output/../^[^O]\S/ and next; /^ / and print;' ../../src/ s/Second started\n//; # Due to multiple jobs "tried 2" often ends up wrong s/tried 2\n//; + # Due to order is often mixed up + s/echo \d; exit \d\n/echo X; exit X\n/; ' # 3+3 .par files (from --files), 1 .tms-file from tmux attach find {$TMPDIR,/var/tmp,/tmp}/{fif,tms,par[^a]}* -mmin -10 2>/dev/null | wc -l diff --git a/testsuite/wanted-results/parallel-local-3s b/testsuite/wanted-results/parallel-local-3s index 9e28038f..0031ddd4 100644 --- a/testsuite/wanted-results/parallel-local-3s +++ b/testsuite/wanted-results/parallel-local-3s @@ -687,7 +687,7 @@ bash---pstree ** parallel: SIGTERM received. No new jobs will be started. parallel: Waiting for these 1 jobs to finish. Send SIGTERM again to stop now. -parallel: bash -c sleep\ 120\ \&\ pid=\$\!\;\ wait\ \$pid 1 +parallel: bash -c sleep\ 120\ \&\ pid\=\$\!\;\ wait\ \$pid 1 echo '### Are children killed if GNU Parallel receives INT twice? There should be no sleep at the end' ### Are children killed if GNU Parallel receives INT twice? There should be no sleep at the end parallel -q bash -c 'sleep 120 & pid=$!; wait $pid' ::: 1 & T=$!; sleep 2; pstree $$; kill -INT $T; sleep 1; pstree $$; diff --git a/testsuite/wanted-results/parallel-local-ssh1 b/testsuite/wanted-results/parallel-local-ssh1 index f95a0403..5d426ab8 100644 --- a/testsuite/wanted-results/parallel-local-ssh1 +++ b/testsuite/wanted-results/parallel-local-ssh1 @@ -12,22 +12,22 @@ echo '### bug #41805: Idea: propagate --env for parallel --number-of-cores' ### bug #41805: Idea: propagate --env for parallel --number-of-cores echo '** test_zsh' ** test_zsh - FOO=test_zsh parallel --env FOO,HOME -S zsh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_zsh parallel --env FOO,HOME -S zsh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' FOO=test_zsh HOME=/home/tange echo '** test_zsh_filter' ** test_zsh_filter - FOO=test_zsh_filter parallel --filter-hosts --env FOO,HOME -S zsh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_zsh_filter parallel --filter-hosts --env FOO,HOME -S zsh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' FOO=test_zsh_filter HOME=/home/tange echo '** test_csh' ** test_csh - FOO=test_csh parallel --env FOO,HOME -S csh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_csh parallel --env FOO,HOME -S csh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' FOO=test_csh HOME=/home/tange echo '** test_csh_filter' ** test_csh_filter - FOO=test_csh_filter parallel --filter-hosts --env FOO,HOME -S csh@lo env ::: "" |sort|egrep 'FOO|^HOME' + FOO=test_csh_filter parallel --filter-hosts --env FOO,HOME -S csh@lo -N0 env ::: "" |sort|egrep 'FOO|^HOME' FOO=test_csh_filter HOME=/home/tange echo '** bug #41805 done' diff --git a/testsuite/wanted-results/parallel-local1 b/testsuite/wanted-results/parallel-local1 index e7606d06..07d8f9d0 100644 --- a/testsuite/wanted-results/parallel-local1 +++ b/testsuite/wanted-results/parallel-local1 @@ -203,7 +203,7 @@ a_b_c_d echo '### Test of bug: If input is empty string' ### Test of bug: If input is empty string (echo ; echo abcbdbebf;echo abc) | parallel -k --colsep b -v echo {1}{2} -echo +echo '' echo ac ac @@ -338,13 +338,13 @@ echo '### Test -E' echo '### Test -E one empty' ### Test -E one empty seq 1 100 | parallel -k -E 3 echo :::: - ::: 2 3 4 5 6 7 8 9 10 :::: <(seq 3 11) -1 2 -2 2 +1 2 +2 2 echo '### Test -E 2 empty' ### Test -E 2 empty seq 1 100 | parallel -k -E 3 echo :::: - ::: 3 4 5 6 7 8 9 10 :::: <(seq 3 11) -1 -2 +1 +2 echo '### Test -E all empty' ### Test -E all empty seq 3 100 | parallel -k -E 3 echo :::: - ::: 3 4 5 6 7 8 9 10 :::: <(seq 3 11) diff --git a/testsuite/wanted-results/parallel-local104 b/testsuite/wanted-results/parallel-local104 index 8938e877d1e12e93c3cc484c14373e65e9866235..09a30b5d788e74f58cac269270dce33c6f8c3427 100644 GIT binary patch delta 117 zcmWN}!41PO2mnASJLK1gHz)>!VT#NUW7wiQ#2a;{Nc}eh+}+!~UGEZMDGH)}R;Z^~ z1*y;@)h#>aI=DEwVzvnxs};5M<&2TLnXk2gsJ3pzSeh7R11bvi%F=kUh8vu>!ZkfXv6wl Ef1Btf2mk;8 diff --git a/testsuite/wanted-results/parallel-local105 b/testsuite/wanted-results/parallel-local105 index 257ce621..9277e9e1 100644 --- a/testsuite/wanted-results/parallel-local105 +++ b/testsuite/wanted-results/parallel-local105 @@ -1,8 +1,8 @@ -60d6db97611d90fd01e6b4db39db99fd - +04f23d767b301409aac59a612efcd727 - There are 6246 dirs with 6246 files Removing files -efc48d4bbb99af2d4c4a76b08c2529bb - +643fe9e7808976565b33a6fbc932428b - There are 6246 dirs with files Removing dirs -e5f7d474805e628a5dfe299713000a6a - +7d89b0dc655b91f358a5cee5f4b2d1d7 - There are 1 dirs with files diff --git a/testsuite/wanted-results/parallel-local114 b/testsuite/wanted-results/parallel-local114 index 65b4d906e27584e7cb949080ecebde5da6c186d0..04a48e30b858dc2e481aeb9e9747c9c6ce28cff6 100644 GIT binary patch delta 14 VcmdlSwIyo99xg_P&3m}Yl>jg(1*HH0 delta 12 TcmdlIwK;0T9(wc) >(md5sum) >/dev/null; wait +echo '### Test -m with 60000 args'; seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -km echo a{}b{.}c{.} | tee >(wc) >(md5sum) >/dev/null; wait ### Test -m with 60000 args -cded9cd15e00550b08e57afc0172caa8 - - 12 180000 1286718 -echo '### Test -X with 60000 args'; seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.} | tee >(wc) >(md5sum) >/dev/null; wait +565b18712ac24f5c46f6e64cf4548733 - + 10 179980 1286692 +echo '### Test -X with 60000 args'; seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.} | tee >(wc) >(md5sum) >/dev/null; wait ### Test -X with 60000 args -12de4813eda45d364a51bef697eee299 - - 13 120000 1586682 +f09f466888e1c737eb581f41cb0087ba - + 11 60000 1346682 echo '### Test -X with 60000 args and 5 expansions' ### Test -X with 60000 args and 5 expansions -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.}{.}{} | wc -l -19 -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.}{.} | wc -l -15 -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.} | wc -l +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.}{.}{} | wc -l +17 +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.}{.} | wc -l 13 -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c | wc -l -10 -seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b | wc -l -7 +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.} | wc -l +11 +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c | wc -l +9 +seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b | wc -l +6 echo '### Test {.} does not repeat more than {}' ### Test {.} does not repeat more than {} -seq 1 15 | perl -pe 's/$/.gif\n/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.} -a1.gifb1c1 abc a2.gifb2c2 abc a3.gifb3c3 abc a4.gifb4c4 abc a5.gifb5c5 abc -a6.gifb6c6 abc a7.gifb7c7 abc a8.gifb8c8 abc a9.gifb9c9 abc a10.gifb10c10 -abc a11.gifb11c11 abc a12.gifb12c12 abc a13.gifb13c13 abc a14.gifb14c14 -abc a15.gifb15c15 abc -seq 1 15 | perl -pe 's/$/.gif\n/' | parallel -j1 -s 80 -km echo a{}b{.}c{.} -a1.gif 2.gif 3.gif 4.gif 5.gif b1 2 3 4 5 c1 2 3 4 5 -a6.gif 7.gif 8.gif 9.gif 10.gif b6 7 8 9 10 c6 7 8 9 10 -a11.gif 12.gif 13.gif 14.gif b11 12 13 14 c11 12 13 14 -a15.gif b15 c15 +seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.} +a1.gifb1c1 a2.gifb2c2 a3.gifb3c3 a4.gifb4c4 a5.gifb5c5 a6.gifb6c6 +a7.gifb7c7 a8.gifb8c8 a9.gifb9c9 a10.gifb10c10 a11.gifb11c11 a12.gifb12c12 +a13.gifb13c13 a14.gifb14c14 a15.gifb15c15 +seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -km echo a{}b{.}c{.} +a1.gif 2.gif 3.gif 4.gif 5.gif 6.gif 7.gifb1 2 3 4 5 6 7c1 2 3 4 5 6 7 +a8.gif 9.gif 10.gif 11.gif 12.gif 13.gifb8 9 10 11 12 13c8 9 10 11 12 13 +a14.gif 15.gifb14 15c14 15 seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.} a1.gifb1c1 a2.gifb2c2 a3.gifb3c3 a4.gifb4c4 a5.gifb5c5 a6.gifb6c6 a7.gifb7c7 a8.gifb8c8 a9.gifb9c9 a10.gifb10c10 a11.gifb11c11 a12.gifb12c12 diff --git a/testsuite/wanted-results/parallel-local22 b/testsuite/wanted-results/parallel-local22 index 806b30ed..6bc10e2d 100644 --- a/testsuite/wanted-results/parallel-local22 +++ b/testsuite/wanted-results/parallel-local22 @@ -83,7 +83,7 @@ echo '### bug #42902: profiles containing arguments with space' echo "--rpl 'FULLPATH chomp(\$_=\"/bin/bash=\".\`readlink -f \$_\`);' " > ~/.parallel/FULLPATH; parallel -JFULLPATH echo FULLPATH ::: $0 /bin/bash=/bin/bash PARALLEL="--rpl 'FULLPATH chomp(\$_=\"/bin/bash=\".\`readlink -f \$_\`);' -v" parallel echo FULLPATH ::: $0 -echo /bin/bash=/bin/bash +echo /bin/bash\=/bin/bash /bin/bash=/bin/bash PARALLEL="--rpl 'FULLPATH chomp(\$_=\"/bin/bash=\".\`readlink -f \$_\`);' perl -e \'print \\\"@ARGV\\\n\\\"\' " parallel With script in \\\$PARALLEL FULLPATH ::: . With script in $PARALLEL /bin/bash=/home/tange/privat/parallel/testsuite diff --git a/testsuite/wanted-results/parallel-tutorial b/testsuite/wanted-results/parallel-tutorial index 7772b39c..0d1be3da 100644 --- a/testsuite/wanted-results/parallel-tutorial +++ b/testsuite/wanted-results/parallel-tutorial @@ -507,28 +507,28 @@ Seq Host Starttime JobRuntime Send Receive Exitval Signal Command 1 2 parallel: This job failed: -echo 1; exit 1 +echo X; exit X parallel: Starting no more jobs. Waiting for 1 jobs to finish. parallel: This job failed: -echo 2; exit 2 +echo X; exit X parallel -j2 --halt now,fail=1 echo {}\; exit {} ::: 0 0 1 2 3 0 0 1 parallel: This job failed: -echo 1; exit 1 +echo X; exit X parallel -j2 --halt soon,fail=20% echo {}\; exit {} ::: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 parallel: This job failed: -echo 1; exit 1 +echo X; exit X parallel: This job failed: -echo 2; exit 2 +echo X; exit X parallel: Starting no more jobs. Waiting for 1 jobs to finish. parallel: This job failed: -echo 3; exit 3 +echo X; exit X parallel -j2 --halt soon,success=1 echo {}\; exit {} ::: 1 2 3 0 4 5 6 1 2 @@ -536,7 +536,7 @@ echo 3; exit 3 0 4 parallel: This job succeeded: -echo 0; exit 0 +echo X; exit X parallel: Starting no more jobs. Waiting for 1 jobs to finish. parallel -k --retries 3 'echo tried {} >>/tmp/runs; echo completed {}; exit {}' ::: 1 2 0 cat /tmp/runs @@ -733,7 +733,7 @@ _ /bin/bash: my_func2: command not found parallel -vv -S $SERVER1 echo ::: bar -ssh parallel@lo exec perl\ -e\ \\\$ENV\\\{\\\"PARALLEL_PID\\\"\\\}=\\\"000000\\\"\\\;\\\$ENV\\\{\\\"PARALLEL_SEQ\\\"\\\}=\\\"1\\\"\\\;\\\$bashfunc\\\ =\\\ \\\"\\\"\\\;@ARGV=\\\"echo\\\ bar\\\"\\\;\\\$shell=\\\"\\\$ENV\\\{SHELL\\\}\\\"\\\;\\\$tmpdir=\\\"/tmp/parallel-tutorial\\\"\\\;do\\\{\\\$ENV\\\{PARALLEL_TMP\\\}=\\\$tmpdir.\\\"/par\\\".join\\\"\\\",map\\\{\\\(0..9,\\\"a\\\"..\\\"z\\\",\\\"A\\\"..\\\"Z\\\"\\\)\\\[rand\\\(62\\\)\\\]\\\}\\\(1..5\\\)\\\;\\\}while\\\(-e\\\$ENV\\\{PARALLEL_TMP\\\}\\\)\\\;\\\$SIG\\\{CHLD\\\}=sub\\\{\\\$done=1\\\;\\\}\\\;\\\$pid=fork\\\;unless\\\(\\\$pid\\\)\\\{setpgrp\\\;exec\\\$shell,\\\"-c\\\",\\\(\\\$bashfunc.\\\"@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\\\); +ssh parallel@lo exec perl\ -e\ \\\$ENV\\\{\\\"PARALLEL_PID\\\"\\\}\\\=\\\"000000\\\"\\\;\\\$ENV\\\{\\\"PARALLEL_SEQ\\\"\\\}\\\=\\\"1\\\"\\\;\\\$bashfunc\\\ \\\=\\\ \\\"\\\"\\\;@ARGV\\\=\\\"echo\\\ bar\\\"\\\;\\\$shell\\\=\\\"\\\$ENV\\\{SHELL\\\}\\\"\\\;\\\$tmpdir\\\=\\\"/tmp/parallel-tutorial\\\"\\\;do\\\{\\\$ENV\\\{PARALLEL_TMP\\\}\\\=\\\$tmpdir.\\\"/par\\\".join\\\"\\\",map\\\{\\\(0..9,\\\"a\\\"..\\\"z\\\",\\\"A\\\"..\\\"Z\\\"\\\)\\\[rand\\\(62\\\)\\\]\\\}\\\(1..5\\\)\\\;\\\}while\\\(-e\\\$ENV\\\{PARALLEL_TMP\\\}\\\)\\\;\\\$SIG\\\{CHLD\\\}\\\=sub\\\{\\\$done\\\=1\\\;\\\}\\\;\\\$pid\\\=fork\\\;unless\\\(\\\$pid\\\)\\\{setpgrp\\\;exec\\\$shell,\\\"-c\\\",\\\(\\\$bashfunc.\\\"@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\\\); bar my_func3() { echo in my_func $1 > $1.out