parallel: Specialized shell_quote_scalar for each shell.

Newline quoting for csh. Empty argument quoted as ''. Passes testsuite.
This commit is contained in:
Ole Tange 2015-05-25 02:27:30 +02:00
parent e892e2fcb6
commit 6a6a5e4d01
14 changed files with 164 additions and 100 deletions

View file

@ -969,7 +969,8 @@ sub parse_options {
} }
if(defined $opt::nonall) { if(defined $opt::nonall) {
# Append a dummy empty argument # 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) { if(defined $opt::tty) {
# Defaults for --tty: -j1 -u # Defaults for --tty: -j1 -u
@ -1266,7 +1267,9 @@ sub parse_semaphore {
::wait_and_exit(255); ::wait_and_exit(255);
} }
@opt::a = ("/dev/null"); @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; $Semaphore::timeout = $opt::semaphoretimeout || 0;
if(defined $opt::semaphorename) { if(defined $opt::semaphorename) {
$Semaphore::name = $opt::semaphorename; $Semaphore::name = $opt::semaphorename;
@ -1639,43 +1642,95 @@ sub shell_quote {
# @strings = strings to be quoted # @strings = strings to be quoted
# Output: # Output:
# @shell_quoted_strings = string quoted with \ as needed by the shell # @shell_quoted_strings = string quoted with \ as needed by the shell
my @strings = (@_); return wantarray ?
for my $a (@strings) { (map { shell_quote_scalar($_) } @_)
$a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; : (join" ",map { shell_quote_scalar($_) } @_);
$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";
} }
sub 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: # Inputs:
# $string = string to be quoted # $string = string to be quoted
# Returns: # Returns:
# $shell_quoted = string quoted with \ as needed by the shell # $shell_quoted = string quoted as needed by the shell
my $a = $_[0];
if(defined $a) { sub shell_quote_scalar_rc {
# Solaris sh wants ^ quoted. # Quote for the rc-shell
# $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; my $a = $_[0];
# This is 1% faster than the above if(defined $a) {
$a =~ s/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\>\<\~\|\; \"\!\$\&\'\202-\377]/\\$&/go; if(($a =~ s/'/''/g)
$a =~ s/[\n]/'\n'/go; # filenames with '\n' is quoted using \' +
($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 { sub shell_quote_file {
@ -2933,7 +2988,7 @@ sub onall {
} }
my ($input_source_fh_ref,@command) = @_; my ($input_source_fh_ref,@command) = @_;
if($Global::quoting) { if($Global::quoting) {
@command = shell_quote_empty(@command); @command = shell_quote(@command);
} }
# Copy all @input_source_fh (-a and :::) into tempfiles # Copy all @input_source_fh (-a and :::) into tempfiles
@ -3665,9 +3720,9 @@ sub which {
# All shells known to mankind # All shells known to mankind
# #
# ash bash csh dash fdsh fish fizsh ksh ksh93 mksh pdksh # 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 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), sash sh static-sh tcsh yash zsh -sh -csh),
'-sh (sh)' # sh on FreeBSD '-sh (sh)' # sh on FreeBSD
); );
@ -8638,7 +8693,8 @@ sub get {
if(defined $Global::max_number_of_args if(defined $Global::max_number_of_args
and $Global::max_number_of_args == 0) { and $Global::max_number_of_args == 0) {
::debug("run", "Read 1 but return 0 args\n"); ::debug("run", "Read 1 but return 0 args\n");
return [Arg->new("")]; # \0 => nothing (not the empty string)
return [Arg->new("\0")];
} else { } else {
return $ret; return $ret;
} }
@ -8981,6 +9037,14 @@ sub new {
}, ref($class) || $class; }, 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; my %perleval;

View file

@ -14,13 +14,13 @@ echo '### Can csh propagate a variable containing \n';
echo '### bug #41805: Idea: propagate --env for parallel --number-of-cores' echo '### bug #41805: Idea: propagate --env for parallel --number-of-cores'
echo '** test_zsh' 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' 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' 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' 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 '** bug #41805 done'
echo '### Deal with long command lines on remote servers' echo '### Deal with long command lines on remote servers'

View file

@ -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{.} seq 1 6 | parallel -k printf '{}.gif\\n' | parallel -j1 -kX echo a{}b{.}c{.}
echo '### Test -m with 60000 args'; 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{.} | parallel -j1 -km echo a{}b{.}c{.} |
tee >(wc) >(md5sum) >/dev/null; tee >(wc) >(md5sum) >/dev/null;
wait wait
echo '### Test -X with 60000 args'; 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{.} | parallel -j1 -kX echo a{}b{.}c{.} |
tee >(wc) >(md5sum) >/dev/null; tee >(wc) >(md5sum) >/dev/null;
wait wait
echo '### Test -X with 60000 args and 5 expansions' 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/' | 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/' | 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/' | 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/' | 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 | wc -l
echo '### Test {.} does not repeat more than {}' 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/' | 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 -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 -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 -km echo a{}b{.}c{.}

View file

@ -57,6 +57,8 @@ perl -ne '$/="\n\n"; /^Output/../^[^O]\S/ and next; /^ / and print;' ../../src/
s/Second started\n//; s/Second started\n//;
# Due to multiple jobs "tried 2" often ends up wrong # Due to multiple jobs "tried 2" often ends up wrong
s/tried 2\n//; 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 # 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 find {$TMPDIR,/var/tmp,/tmp}/{fif,tms,par[^a]}* -mmin -10 2>/dev/null | wc -l

View file

@ -687,7 +687,7 @@ bash---pstree
** **
parallel: SIGTERM received. No new jobs will be started. parallel: SIGTERM received. No new jobs will be started.
parallel: Waiting for these 1 jobs to finish. Send SIGTERM again to stop now. 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' 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 ### 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 $$; parallel -q bash -c 'sleep 120 & pid=$!; wait $pid' ::: 1 & T=$!; sleep 2; pstree $$; kill -INT $T; sleep 1; pstree $$;

View file

@ -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 ### bug #41805: Idea: propagate --env for parallel --number-of-cores
echo '** test_zsh' echo '** test_zsh'
** 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 FOO=test_zsh
HOME=/home/tange HOME=/home/tange
echo '** test_zsh_filter' echo '** test_zsh_filter'
** 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 FOO=test_zsh_filter
HOME=/home/tange HOME=/home/tange
echo '** test_csh' echo '** test_csh'
** 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 FOO=test_csh
HOME=/home/tange HOME=/home/tange
echo '** test_csh_filter' echo '** test_csh_filter'
** 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 FOO=test_csh_filter
HOME=/home/tange HOME=/home/tange
echo '** bug #41805 done' echo '** bug #41805 done'

View file

@ -203,7 +203,7 @@ a_b_c_d
echo '### Test of bug: If input is empty string' echo '### Test of bug: If input is empty string'
### 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 abcbdbebf;echo abc) | parallel -k --colsep b -v echo {1}{2}
echo echo ''
echo ac echo ac
ac ac

View file

@ -1,8 +1,8 @@
60d6db97611d90fd01e6b4db39db99fd - 04f23d767b301409aac59a612efcd727 -
There are 6246 dirs with 6246 files There are 6246 dirs with 6246 files
Removing files Removing files
efc48d4bbb99af2d4c4a76b08c2529bb - 643fe9e7808976565b33a6fbc932428b -
There are 6246 dirs with files There are 6246 dirs with files
Removing dirs Removing dirs
e5f7d474805e628a5dfe299713000a6a - 7d89b0dc655b91f358a5cee5f4b2d1d7 -
There are 1 dirs with files There are 1 dirs with files

View file

@ -1058,7 +1058,7 @@ echo '### -IARG echo from ARG to xARGy < space.xi'
### -IARG echo from ARG to xARGy < space.xi ### -IARG echo from ARG to xARGy < space.xi
stdout xargs -IARG echo from ARG to xARGy < space.xi stdout xargs -IARG echo from ARG to xARGy < space.xi
stdout parallel -k -IARG echo from ARG to xARGy < space.xi stdout parallel -k -IARG echo from ARG to xARGy < space.xi
from to xy from to xy
from to x y from to x y
echo '### printf "\[%s\]\n" < verticaltabs.xi' echo '### printf "\[%s\]\n" < verticaltabs.xi'
### printf "\[%s\]\n" < verticaltabs.xi ### printf "\[%s\]\n" < verticaltabs.xi
@ -1340,7 +1340,7 @@ stdout xargs -t echo this plus that < space.xi
echo this plus that echo this plus that
this plus that this plus that
stdout parallel -k -t echo this plus that < space.xi stdout parallel -k -t echo this plus that < space.xi
echo this plus that echo this plus that ''
echo this plus that \ \ \ \ \ echo this plus that \ \ \ \ \
this plus that this plus that
this plus that this plus that

View file

@ -105,38 +105,36 @@ seq 1 6 | parallel -k printf '{}.gif\\n' | parallel -j1 -km echo a{}b{.}c{.}
a1.gif 2.gif 3.gif 4.gif 5.gif 6.gifb1 2 3 4 5 6c1 2 3 4 5 6 a1.gif 2.gif 3.gif 4.gif 5.gif 6.gifb1 2 3 4 5 6c1 2 3 4 5 6
seq 1 6 | parallel -k printf '{}.gif\\n' | parallel -j1 -kX echo a{}b{.}c{.} seq 1 6 | parallel -k printf '{}.gif\\n' | parallel -j1 -kX echo a{}b{.}c{.}
a1.gifb1c1 a2.gifb2c2 a3.gifb3c3 a4.gifb4c4 a5.gifb5c5 a6.gifb6c6 a1.gifb1c1 a2.gifb2c2 a3.gifb3c3 a4.gifb4c4 a5.gifb5c5 a6.gifb6c6
echo '### Test -m with 60000 args'; seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -km echo a{}b{.}c{.} | tee >(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 ### Test -m with 60000 args
cded9cd15e00550b08e57afc0172caa8 - 565b18712ac24f5c46f6e64cf4548733 -
12 180000 1286718 10 179980 1286692
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 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 ### Test -X with 60000 args
12de4813eda45d364a51bef697eee299 - f09f466888e1c737eb581f41cb0087ba -
13 120000 1586682 11 60000 1346682
echo '### Test -X with 60000 args and 5 expansions' echo '### Test -X with 60000 args and 5 expansions'
### 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 seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b{.}c{.}{.}{} | wc -l
19 17
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
15
seq 1 60000 | perl -pe 's/$/.gif\n/' | parallel -j1 -kX echo a{}b{.}c{.} | wc -l
13 13
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
10 11
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
7 9
seq 1 60000 | perl -pe 's/$/.gif/' | parallel -j1 -kX echo a{}b | wc -l
6
echo '### Test {.} does not repeat more than {}' echo '### Test {.} does not repeat more than {}'
### 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{.} seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -kX echo a{}b{.}c{.}
a1.gifb1c1 abc a2.gifb2c2 abc a3.gifb3c3 abc a4.gifb4c4 abc a5.gifb5c5 abc a1.gifb1c1 a2.gifb2c2 a3.gifb3c3 a4.gifb4c4 a5.gifb5c5 a6.gifb6c6
a6.gifb6c6 abc a7.gifb7c7 abc a8.gifb8c8 abc a9.gifb9c9 abc a10.gifb10c10 a7.gifb7c7 a8.gifb8c8 a9.gifb9c9 a10.gifb10c10 a11.gifb11c11 a12.gifb12c12
abc a11.gifb11c11 abc a12.gifb12c12 abc a13.gifb13c13 abc a14.gifb14c14 a13.gifb13c13 a14.gifb14c14 a15.gifb15c15
abc a15.gifb15c15 abc seq 1 15 | perl -pe 's/$/.gif/' | parallel -j1 -s 80 -km echo a{}b{.}c{.}
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 6.gif 7.gifb1 2 3 4 5 6 7c1 2 3 4 5 6 7
a1.gif 2.gif 3.gif 4.gif 5.gif b1 2 3 4 5 c1 2 3 4 5 a8.gif 9.gif 10.gif 11.gif 12.gif 13.gifb8 9 10 11 12 13c8 9 10 11 12 13
a6.gif 7.gif 8.gif 9.gif 10.gif b6 7 8 9 10 c6 7 8 9 10 a14.gif 15.gifb14 15c14 15
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{.} 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 a1.gifb1c1 a2.gifb2c2 a3.gifb3c3 a4.gifb4c4 a5.gifb5c5 a6.gifb6c6
a7.gifb7c7 a8.gifb8c8 a9.gifb9c9 a10.gifb10c10 a11.gifb11c11 a12.gifb12c12 a7.gifb7c7 a8.gifb8c8 a9.gifb9c9 a10.gifb10c10 a11.gifb11c11 a12.gifb12c12

View file

@ -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 echo "--rpl 'FULLPATH chomp(\$_=\"/bin/bash=\".\`readlink -f \$_\`);' " > ~/.parallel/FULLPATH; parallel -JFULLPATH echo FULLPATH ::: $0
/bin/bash=/bin/bash /bin/bash=/bin/bash
PARALLEL="--rpl 'FULLPATH chomp(\$_=\"/bin/bash=\".\`readlink -f \$_\`);' -v" parallel echo FULLPATH ::: $0 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 /bin/bash=/bin/bash
PARALLEL="--rpl 'FULLPATH chomp(\$_=\"/bin/bash=\".\`readlink -f \$_\`);' perl -e \'print \\\"@ARGV\\\n\\\"\' " parallel With script in \\\$PARALLEL FULLPATH ::: . 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 With script in $PARALLEL /bin/bash=/home/tange/privat/parallel/testsuite

View file

@ -507,28 +507,28 @@ Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 1
2 2
parallel: This job failed: parallel: This job failed:
echo 1; exit 1 echo X; exit X
parallel: Starting no more jobs. Waiting for 1 jobs to finish. parallel: Starting no more jobs. Waiting for 1 jobs to finish.
parallel: This job failed: 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 parallel -j2 --halt now,fail=1 echo {}\; exit {} ::: 0 0 1 2 3
0 0
0 0
1 1
parallel: This job failed: 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 parallel -j2 --halt soon,fail=20% echo {}\; exit {} ::: 0 1 2 3 4 5 6 7 8 9
0 0
1 1
2 2
3 3
parallel: This job failed: parallel: This job failed:
echo 1; exit 1 echo X; exit X
parallel: This job failed: parallel: This job failed:
echo 2; exit 2 echo X; exit X
parallel: Starting no more jobs. Waiting for 1 jobs to finish. parallel: Starting no more jobs. Waiting for 1 jobs to finish.
parallel: This job failed: 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 parallel -j2 --halt soon,success=1 echo {}\; exit {} ::: 1 2 3 0 4 5 6
1 1
2 2
@ -536,7 +536,7 @@ echo 3; exit 3
0 0
4 4
parallel: This job succeeded: parallel: This job succeeded:
echo 0; exit 0 echo X; exit X
parallel: Starting no more jobs. Waiting for 1 jobs to finish. 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 parallel -k --retries 3 'echo tried {} >>/tmp/runs; echo completed {}; exit {}' ::: 1 2 0
cat /tmp/runs cat /tmp/runs
@ -733,7 +733,7 @@ _
/bin/bash: my_func2: command not found /bin/bash: my_func2: command not found
parallel -vv -S $SERVER1 echo ::: bar 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 bar
my_func3() { my_func3() {
echo in my_func $1 > $1.out echo in my_func $1 > $1.out