parallel: --env includes test + man and works for t?csh, too.

This commit is contained in:
Ole Tange 2012-10-15 15:47:10 +02:00
parent b2f8450bf3
commit dd5093f8b4
4 changed files with 62 additions and 26 deletions

View file

@ -208,6 +208,7 @@ if($::opt_nonall or $::opt_onall) {
((defined $::opt_D) ? "-D" : ""), ((defined $::opt_D) ? "-D" : ""),
((defined $::opt_timeout) ? "--timeout ".$::opt_timeout : ""), ((defined $::opt_timeout) ? "--timeout ".$::opt_timeout : ""),
((defined $::opt_plain) ? "--plain" : ""), ((defined $::opt_plain) ? "--plain" : ""),
((defined @::opt_env) ? map { "--env ".::shell_quote_scalar($_) } @::opt_env : ""),
); );
::debug("| $0 $options\n"); ::debug("| $0 $options\n");
open(PARALLEL,"| $0 -j0 $options") || open(PARALLEL,"| $0 -j0 $options") ||
@ -605,7 +606,7 @@ sub get_options_from_array {
sub parse_options { sub parse_options {
# Returns: N/A # Returns: N/A
# Defaults: # Defaults:
$Global::version = 20120930; $Global::version = 20121015;
$Global::progname = 'parallel'; $Global::progname = 'parallel';
$Global::infinity = 2**31; $Global::infinity = 2**31;
$Global::debug = 0; $Global::debug = 0;
@ -837,6 +838,12 @@ sub parse_options {
open_joblog(); open_joblog();
} }
sub env_quote {
my $v = shift;
$v =~ s/([ \n\&\<\>\(\)\;\'\{\}\t\"\$\`\*\174\!\?\~])/\\$1/g;
return $v;
}
sub parse_env_var { sub parse_env_var {
# Parse --env and set $Global::envvar # Parse --env and set $Global::envvar
# Returns: N/A # Returns: N/A
@ -846,15 +853,22 @@ sub parse_env_var {
# Split up --env VAR1,VAR2 # Split up --env VAR1,VAR2
push @vars, split /,/, $varstring; push @vars, split /,/, $varstring;
} }
# Keep only defined variables
@vars = grep { defined($ENV{$_}) } @vars;
my @qcsh = map { my $a=$_; "setenv $a " . env_quote($ENV{$a}) } @vars;
my @qbash = map { my $a=$_; "export $a=" . env_quote($ENV{$a}) } @vars;
# Create lines like:
# echo $SHELL | grep -E "/t?csh" >/dev/null && setenv V1 val1 && setenv V2 val2 || export V1=val1 && export V2=val2 ; echo "$V1$V2"
if(@vars) {
$Global::envvar = $Global::envvar =
(q{eval `echo $SHELL | grep -E "/(t)?csh" > /dev/null} join"",
. q{ && echo } (q{echo $SHELL | grep -E "/t?csh" > /dev/null && }
. join("", map { "setenv $_ " . join(" && ", @qcsh)
. ::shell_quote_scalar(::shell_quote_scalar($ENV{$_})).'\;' } @vars) . q{ || }
. q{ || echo } . join(" && ", @qbash)
. join("", map { "export $_=" .q{;});
. ::shell_quote_scalar(::shell_quote_scalar($ENV{$_})).'\;' } @vars) }
.q{`;});
$Global::envvarlen = length $Global::envvar; $Global::envvarlen = length $Global::envvar;
} }
@ -1041,7 +1055,7 @@ sub __QUOTING_ARGUMENTS_FOR_SHELL__ {}
sub shell_quote { sub shell_quote {
my @strings = (@_); my @strings = (@_);
for my $a (@strings) { for my $a (@strings) {
$a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\*\>\<\~\|\; \"\!\$\&\'])/\\$1/g; $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g;
$a =~ s/[\n]/'\n'/g; # filenames with '\n' is quoted using \' $a =~ s/[\n]/'\n'/g; # filenames with '\n' is quoted using \'
} }
return wantarray ? @strings : "@strings"; return wantarray ? @strings : "@strings";
@ -1052,7 +1066,7 @@ sub shell_quote_scalar {
# Returns: # Returns:
# string quoted with \ as needed by the shell # string quoted with \ as needed by the shell
my $a = shift; my $a = shift;
$a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\*\>\<\~\|\; \"\!\$\&\'])/\\$1/g; $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g;
$a =~ s/[\n]/'\n'/g; # filenames with '\n' is quoted using \' $a =~ s/[\n]/'\n'/g; # filenames with '\n' is quoted using \'
return $a; return $a;
} }

View file

@ -445,6 +445,15 @@ If I<eof-str> is omitted, there is no end of file string. If neither
B<-E> nor B<-e> is used, no end of file string is used. B<-E> nor B<-e> is used, no end of file string is used.
=item B<--env> I<var>
Copy environment variable I<var>. This will copy I<var> to the
environment that the command is run in. This is especially useful for
remote environments.
Caveat: If I<var> contains newline ('\n') the value is messed up.
=item B<--eta> =item B<--eta>
Show the estimated number of seconds before finishing. This forces GNU Show the estimated number of seconds before finishing. This forces GNU

View file

@ -3,24 +3,28 @@
echo '### Test slow arguments generation - https://savannah.gnu.org/bugs/?32834' echo '### Test slow arguments generation - https://savannah.gnu.org/bugs/?32834'
seq 1 3 | parallel -j1 "sleep 2; echo {}" | parallel -kj2 echo seq 1 3 | parallel -j1 "sleep 2; echo {}" | parallel -kj2 echo
echo '### Test --env - https://savannah.gnu.org/bugs/?37351'
export TWOSPACES=' 2 spaces '
export THREESPACES=" > My brother's 12\" records < "
parallel --env TWOSPACES echo 'a"$TWOSPACES"b' ::: 1
parallel --env TWOSPACES --env THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2
parallel --env TWOSPACES,THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2a
parallel -S localhost --env TWOSPACES echo 'a"$TWOSPACES"b' ::: 1
parallel -S localhost --env TWOSPACES --env THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2
parallel -S localhost --env TWOSPACES,THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2a
parallel -S csh@localhost --env TWOSPACES echo 'a"$TWOSPACES"b' ::: 1
parallel -S csh@localhost --env TWOSPACES --env THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2
parallel -S csh@localhost --env TWOSPACES,THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2a
echo '### Test too slow spawning' echo '### Test too slow spawning'
killall -9 burnP6 2>/dev/null killall -9 burnP6 2>/dev/null
seq 1 2 | parallel -j2 -N0 timeout -k 25 26 burnP6 & seq `parallel --number-of-cores` | parallel -j100% -N0 timeout -k 25 26 burnP6 &
sleep 1 sleep 1
seq 1 1000 | seq 1 1000 |
stdout nice nice parallel -s 100 -uj0 true | stdout nice nice parallel -s 100 -uj0 true |
perl -pe '/parallel: Warning: Starting \d+ processes took/ and do {close STDIN; `killall -9 burnP6`; print "OK\n"; exit }' perl -pe '/parallel: Warning: Starting \d+ processes took/ and do {close STDIN; `killall -9 burnP6`; print "OK\n"; exit }'
killall -9 burnP6 2>/dev/null killall -9 burnP6 2>/dev/null
echo '### Test --env - https://savannah.gnu.org/bugs/?37351'
export TWOSPACES=' 2 spaces '
export THREESPACES=" > My brother's 12\" records < "
stdout parallel --env TWOSPACES echo 'a"$TWOSPACES"b' ::: 1
stdout parallel --env TWOSPACES --env THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2
stdout parallel --env TWOSPACES,THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2a
stdout parallel -S localhost --env TWOSPACES echo 'a"$TWOSPACES"b' ::: 1
stdout parallel -S localhost --env TWOSPACES --env THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2
stdout parallel -S localhost --env TWOSPACES,THREESPACES echo 'a"$TWOSPACES"b' 'a"$THREESPACES"b' ::: 2a
echo '### Test --env all chars except \n - single and double - no output is good'
perl -e 'for(1..9,9,11..255) { printf "%c%c %c%d\0",$_,$_,$_,$_ }' | stdout parallel --nice 19 -j4 -k -I // --arg-sep _ -0 V=// V2=V2=// parallel -k -j1 -S :,1/lo,1/tcsh@lo,1/csh@lo --env V,V2 echo \''"{}$V$V2"'\' ::: {#} {#} {#} {#} | uniq -c | grep -v ' 4 '|grep -v xauth |grep -v X11
echo '### Test --env all chars except \n - single and double --onall - no output is good'
perl -e 'for(1..9,9,11..255) { printf "%c%c %c%d\0",$_,$_,$_,$_ }' | stdout parallel --nice 19 -j4 -k -I // --arg-sep _ -0 V=// V2=V2=// parallel -k -j1 -S :,1/lo,1/tcsh@lo,1/csh@lo --onall --env V,V2 echo \''"{}$V$V2"'\' ::: {#} | uniq -c | grep -v ' 4 '|grep -v xauth |grep -v X11

View file

@ -4,3 +4,12 @@
3 3
### Test too slow spawning ### Test too slow spawning
OK OK
### Test --env - https://savannah.gnu.org/bugs/?37351
a 2 spaces b 1
a 2 spaces b a > My brother's 12" records < b 2
a 2 spaces b a > My brother's 12" records < b 2a
a 2 spaces b 1
a 2 spaces b a > My brother's 12" records < b 2
a 2 spaces b a > My brother's 12" records < b 2a
### Test --env all chars except \n - single and double - no output is good
### Test --env all chars except \n - single and double --onall - no output is good