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) {
# 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;

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 '** 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'

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{.}
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{.}

View file

@ -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

View file

@ -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 $$;

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
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'

View file

@ -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)

View file

@ -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

View file

@ -1052,13 +1052,13 @@ echo '### echo this plus that < space.xi'
stdout xargs echo this plus that < space.xi
this plus that
stdout parallel -k echo this plus that < space.xi
this plus that
this plus that
this plus that
echo '### -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 parallel -k -IARG echo from ARG to xARGy < space.xi
from to xy
from to xy
from to x y
echo '### printf "\[%s\]\n" < verticaltabs.xi'
### printf "\[%s\]\n" < verticaltabs.xi
@ -1340,9 +1340,9 @@ stdout xargs -t echo this plus that < space.xi
echo this plus that
this plus that
stdout parallel -k -t echo this plus that < space.xi
echo this plus that
echo this plus that ''
echo this plus that \ \ \ \ \
this plus that
this plus that
this plus that
echo '### -n1 printf "@%s@\n" < empty.xi'
### -n1 printf "@%s@\n" < empty.xi

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
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
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
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

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
/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

View file

@ -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