parset uses --_parset in ash,dash,sh.

env_parallel.*sh shellschecked.
This commit is contained in:
Ole Tange 2022-04-07 00:23:42 +02:00
parent 37528da98b
commit 61d58288aa
19 changed files with 402 additions and 329 deletions

View file

@ -4,6 +4,28 @@
Quote of the month: Quote of the month:
Such a life saver of a tool.
-- winrid@ycombinator
I used GNU Parallel to run a script locally that did what a big distributed system did, quicker and more reliably. It got to the point where people would just ask me to "run the thing" on my laptop instead of waiting for the cron.
-- winrid@ycombinator
Parallel has been (and still is) super useful and simple tool for speeding up all kinds of shell tasks during my career.
-- ValtteriL@ycombinator
parallel is so useful and i use it multiple times daily.
-- arrakeen@ycombinator
Immensely useful which I am forever grateful that it exists.
-- AlexDragusin@ycombinator
Parallel is Good Stuff (tm)
-- bloopernova@ycombinator
GNU Parallel is one of my favorite utilities of all time.
-- paskozdilar@ycombinator
Tool, was ich sehr ausgiebig nutze inzwischen und lieben gelernt habe: "GNU parallel" Tool, was ich sehr ausgiebig nutze inzwischen und lieben gelernt habe: "GNU parallel"
-- nuit @nv1t@twitter -- nuit @nv1t@twitter

View file

@ -254,7 +254,7 @@ from:tange@gnu.org
to:parallel@gnu.org, bug-parallel@gnu.org to:parallel@gnu.org, bug-parallel@gnu.org
stable-bcc: Jesse Alama <jessealama@fastmail.fm> stable-bcc: Jesse Alama <jessealama@fastmail.fm>
Subject: GNU Parallel 20220422 ('#SlavaUkrayini🌻 albright<<>>') released [stable] Subject: GNU Parallel 20220422 ('Буча #SlavaUkrayini #SlavaUkrayini🌻 albright<<>>') released [stable]
GNU Parallel 20220422 ('<<>>') has been released. It is available for download at: lbry://@GnuParallel:4 GNU Parallel 20220422 ('<<>>') has been released. It is available for download at: lbry://@GnuParallel:4

View file

@ -27,6 +27,7 @@
# #
# SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=SC2006 shell=dash
env_parallel() { env_parallel() {
# based on env_parallel.sh # based on env_parallel.sh
@ -36,8 +37,8 @@ env_parallel() {
for _i in `alias 2>/dev/null | perl -ne 's/^alias //;s/^(\S+)=.*/$1/ && print' 2>/dev/null`; do for _i in `alias 2>/dev/null | perl -ne 's/^alias //;s/^(\S+)=.*/$1/ && print' 2>/dev/null`; do
# Check if this name really is an alias # Check if this name really is an alias
# or just part of a multiline alias definition # or just part of a multiline alias definition
if alias $_i >/dev/null 2>/dev/null; then if alias "$_i" >/dev/null 2>/dev/null; then
echo $_i echo "$_i"
fi fi
done done
} }
@ -47,7 +48,7 @@ env_parallel() {
# alias myalias='definition' (FreeBSD ash) # alias myalias='definition' (FreeBSD ash)
# so remove 'alias ' from first line # so remove 'alias ' from first line
for _i in "$@"; do for _i in "$@"; do
echo 'alias '"`alias $_i | perl -pe '1..1 and s/^alias //'`" echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`"
done done
} }
_names_of_maybe_FUNCTIONS() { _names_of_maybe_FUNCTIONS() {
@ -55,6 +56,7 @@ env_parallel() {
} }
_names_of_FUNCTIONS() { _names_of_FUNCTIONS() {
# myfunc is a function # myfunc is a function
# shellcheck disable=SC2046
LANG=C type `_names_of_maybe_FUNCTIONS` | LANG=C type `_names_of_maybe_FUNCTIONS` |
perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"'
} }
@ -70,22 +72,24 @@ env_parallel() {
for _i in "$@" for _i in "$@"
do do
perl -e 'print @ARGV' "$_i=" perl -e 'print @ARGV' "$_i="
eval echo \"\$$_i\" | perl -e '$/=undef; $a=<>; chop($a); print $a' | eval echo "\"\$$_i\"" | perl -e '$/=undef; $a=<>; chop($a); print $a' |
perl -pe 's/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\$&/go;'"s/'/\\\'/g; s/[\n]/'\\n'/go;"; perl -pe 's/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\$&/go;'"s/'/\\\'/g; s/[\n]/'\\n'/go;";
echo echo
done done
} }
_ignore_HARDCODED() { _ignore_HARDCODED() {
# These names cannot be detected # These names cannot be detected
echo '(_|TIMEOUT)' echo '(_|TIMEOUT|IFS)'
} }
_ignore_READONLY() { _ignore_READONLY() {
# shellcheck disable=SC1078,SC1079,SC2026
readonly | perl -e '@r = map { readonly | perl -e '@r = map {
chomp; chomp;
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
# ash: readonly var='val' # ash: readonly var='val'
# ksh: var='val' # ksh: var='val'
s/^(readonly )?([^= ]*)(=.*|)$/$2/ or # mksh: PIPESTATUS[0]
s/^(readonly )?([^=\[ ]*?)(\[\d+\])?(=.*|)$/$2/ or
# bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4") # bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4")
# zsh: typeset -r var='val' # zsh: typeset -r var='val'
s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/; s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/;
@ -96,7 +100,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -203,24 +209,27 @@ env_parallel() {
END { exit not $exit }' END { exit not $exit }'
} }
_warning_PAR() { _warning_PAR() {
echo "env_parallel: Warning: $@" >&2 echo "env_parallel: Warning: $*" >&2
} }
_error_PAR() { _error_PAR() {
echo "env_parallel: Error: $@" >&2 echo "env_parallel: Error: $*" >&2
} }
if _which_PAR parallel >/dev/null; then if _which_PAR parallel >/dev/null; then
true parallel found in path true parallel found in path
else else
# shellcheck disable=SC2016
_error_PAR 'parallel must be in $PATH.' _error_PAR 'parallel must be in $PATH.'
return 255 return 255
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -231,7 +240,7 @@ env_parallel() {
(_names_of_ALIASES; (_names_of_ALIASES;
_names_of_FUNCTIONS; _names_of_FUNCTIONS;
_names_of_VARIABLES) | _names_of_VARIABLES) |
cat > $HOME/.parallel/ignored_vars cat > "$HOME"/.parallel/ignored_vars
return 0 return 0
fi fi
@ -241,6 +250,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -264,6 +274,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -271,6 +282,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -280,6 +292,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -289,6 +302,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -297,6 +311,7 @@ env_parallel() {
fi fi
unset _variable_NAMES unset _variable_NAMES
# shellcheck disable=SC2006
PARALLEL_ENV="` PARALLEL_ENV="`
$_list_alias_BODIES; $_list_alias_BODIES;
$_list_function_BODIES; $_list_function_BODIES;
@ -309,7 +324,8 @@ env_parallel() {
unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE
unset _remove_bad_NAMES _grep_REGEXP unset _remove_bad_NAMES _grep_REGEXP
unset _prefix_PARALLEL_ENV unset _prefix_PARALLEL_ENV
# Test if environment is too big # Test if environment is too big by running 'true'
# shellcheck disable=SC2006,SC2092
if `_which_PAR true` >/dev/null 2>/dev/null ; then if `_which_PAR true` >/dev/null 2>/dev/null ; then
parallel "$@" parallel "$@"
_parallel_exit_CODE=$? _parallel_exit_CODE=$?
@ -363,13 +379,6 @@ _parset_main() {
# parset "var_a4 var_b4 var_c4" echo ::: {1..3} # parset "var_a4 var_b4 var_c4" echo ::: {1..3}
# echo $var_c4 # echo $var_c4
_make_TEMP() {
# mktemp does not exist on some OS
perl -e 'use File::Temp qw(tempfile);
$ENV{"TMPDIR"} ||= "/tmp";
print((tempfile(DIR=>$ENV{"TMPDIR"}, TEMPLATE => "parXXXXX"))[1])'
}
_parset_NAME="$1" _parset_NAME="$1"
if [ "$_parset_NAME" = "" ] ; then if [ "$_parset_NAME" = "" ] ; then
echo parset: Error: No destination variable given. >&2 echo parset: Error: No destination variable given. >&2
@ -385,6 +394,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -400,45 +410,21 @@ _parset_main() {
return 255 return 255
fi fi
shift shift
echo "$_parset_NAME" |
perl -ne 'chomp;for (split /[, ]/) { # Bash: declare -A myassoc=( )
# Allow: var_32 var[3] # Zsh: typeset -A myassoc=( )
if(not /^[a-zA-Z_][a-zA-Z_0-9]*(\[\d+\])?$/) { # Ksh: typeset -A myassoc=( )
print STDERR "parset: Error: $_ is an invalid variable name.\n"; # shellcheck disable=SC2039,SC2169
print STDERR "parset: Error: Variable names must be letter followed by letters or digits.\n"; if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
print STDERR "parset: Error: Usage:\n"; perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
print STDERR "parset: Error: parset varname GNU Parallel options and command\n"; # This is an associative array
$exitval = 255; # shellcheck disable=SC2006
} eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
} # The eval returns the function!
exit $exitval;
' || return 255
_exit_FILE=`_make_TEMP`
if perl -e 'exit not grep /,| /, @ARGV' "$_parset_NAME" ; then
# $_parset_NAME contains , or space
# Split on , or space to get the names
eval "`
# Compute results into files
($_parset_PARALLEL_PRG --files -k "$@"; echo $? > "$_exit_FILE") |
# var1= cat tmpfile1; rm tmpfile1
# var2= cat tmpfile2; rm tmpfile2
parallel -q echo {2}='\`cat {1}; rm {1}\`' :::: - :::+ \`
echo "$_parset_NAME" |
perl -pe 's/,/ /g'
\`
`"
else else
# $_parset_NAME does not contain , or space # This is a normal array or a list of variable names
# => $_parset_NAME is the name of the array to put data into # shellcheck disable=SC2006
# Supported in: bash zsh ksh mksh eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# Arrays do not work in: sh ash dash # The eval returns the function!
eval "$_parset_NAME=( $(
# Compute results into files. Save exit value
($_parset_PARALLEL_PRG --files -k "$@"; echo $? > "$_exit_FILE") |
perl -pe 'chop;$_="\"\`cat $_; rm $_\`\" "'
) )"
fi fi
unset _parset_NAME _parset_PARALLEL_PRG _parallel_exit_CODE
# Unset _exit_FILE before return
eval "unset _exit_FILE; return \`cat $_exit_FILE; rm $_exit_FILE\`"
} }

View file

@ -27,7 +27,6 @@
# #
# SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=SC2006 # shellcheck disable=SC2006
env_parallel() { env_parallel() {
@ -75,7 +74,8 @@ env_parallel() {
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
# ash: readonly var='val' # ash: readonly var='val'
# ksh: var='val' # ksh: var='val'
s/^(readonly )?([^= ]*)(=.*|)$/$2/ or # mksh: PIPESTATUS[0]
s/^(readonly )?([^=\[ ]*?)(\[\d+\])?(=.*|)$/$2/ or
# bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4") # bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4")
# zsh: typeset -r var='val' # zsh: typeset -r var='val'
s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/; s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/;
@ -86,7 +86,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -216,10 +218,12 @@ env_parallel() {
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -244,6 +248,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -269,6 +274,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -276,6 +282,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -285,6 +292,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -294,6 +302,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -387,6 +396,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -406,14 +416,17 @@ _parset_main() {
# Bash: declare -A myassoc=( ) # Bash: declare -A myassoc=( )
# Zsh: typeset -A myassoc=( ) # Zsh: typeset -A myassoc=( )
# Ksh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( )
# shellcheck disable=SC2039,SC2169
if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
# This is an associative array # This is an associative array
eval "`$_parset_PARALLEL_PRG -k --parset assoc,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
else else
# This is a normal array or a list of variable names # This is a normal array or a list of variable names
eval "`$_parset_PARALLEL_PRG -k --parset var,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
fi fi
} }

View file

@ -27,6 +27,7 @@
# #
# SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=SC2006
env_parallel() { env_parallel() {
# based on env_parallel.sh # based on env_parallel.sh
@ -36,8 +37,8 @@ env_parallel() {
for _i in `alias 2>/dev/null | perl -ne 's/^alias //;s/^(\S+)=.*/$1/ && print' 2>/dev/null`; do for _i in `alias 2>/dev/null | perl -ne 's/^alias //;s/^(\S+)=.*/$1/ && print' 2>/dev/null`; do
# Check if this name really is an alias # Check if this name really is an alias
# or just part of a multiline alias definition # or just part of a multiline alias definition
if alias $_i >/dev/null 2>/dev/null; then if alias "$_i" >/dev/null 2>/dev/null; then
echo $_i echo "$_i"
fi fi
done done
} }
@ -47,7 +48,7 @@ env_parallel() {
# alias myalias='definition' (FreeBSD ash) # alias myalias='definition' (FreeBSD ash)
# so remove 'alias ' from first line # so remove 'alias ' from first line
for _i in "$@"; do for _i in "$@"; do
echo 'alias '"`alias $_i | perl -pe '1..1 and s/^alias //'`" echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`"
done done
} }
_names_of_maybe_FUNCTIONS() { _names_of_maybe_FUNCTIONS() {
@ -55,6 +56,7 @@ env_parallel() {
} }
_names_of_FUNCTIONS() { _names_of_FUNCTIONS() {
# myfunc is a function # myfunc is a function
# shellcheck disable=SC2046
LANG=C type `_names_of_maybe_FUNCTIONS` | LANG=C type `_names_of_maybe_FUNCTIONS` |
perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"'
} }
@ -70,22 +72,24 @@ env_parallel() {
for _i in "$@" for _i in "$@"
do do
perl -e 'print @ARGV' "$_i=" perl -e 'print @ARGV' "$_i="
eval echo \"\$$_i\" | perl -e '$/=undef; $a=<>; chop($a); print $a' | eval echo "\"\$$_i\"" | perl -e '$/=undef; $a=<>; chop($a); print $a' |
perl -pe 's/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\$&/go;'"s/'/\\\'/g; s/[\n]/'\\n'/go;"; perl -pe 's/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\$&/go;'"s/'/\\\'/g; s/[\n]/'\\n'/go;";
echo echo
done done
} }
_ignore_HARDCODED() { _ignore_HARDCODED() {
# These names cannot be detected # These names cannot be detected
echo '(_|TIMEOUT)' echo '(_|TIMEOUT|IFS)'
} }
_ignore_READONLY() { _ignore_READONLY() {
# shellcheck disable=SC1078,SC1079,SC2026
readonly | perl -e '@r = map { readonly | perl -e '@r = map {
chomp; chomp;
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
# ash: readonly var='val' # ash: readonly var='val'
# ksh: var='val' # ksh: var='val'
s/^(readonly )?([^= ]*)(=.*|)$/$2/ or # mksh: PIPESTATUS[0]
s/^(readonly )?([^=\[ ]*?)(\[\d+\])?(=.*|)$/$2/ or
# bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4") # bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4")
# zsh: typeset -r var='val' # zsh: typeset -r var='val'
s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/; s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/;
@ -96,7 +100,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -203,24 +209,27 @@ env_parallel() {
END { exit not $exit }' END { exit not $exit }'
} }
_warning_PAR() { _warning_PAR() {
echo "env_parallel: Warning: $@" >&2 echo "env_parallel: Warning: $*" >&2
} }
_error_PAR() { _error_PAR() {
echo "env_parallel: Error: $@" >&2 echo "env_parallel: Error: $*" >&2
} }
if _which_PAR parallel >/dev/null; then if _which_PAR parallel >/dev/null; then
true parallel found in path true parallel found in path
else else
# shellcheck disable=SC2016
_error_PAR 'parallel must be in $PATH.' _error_PAR 'parallel must be in $PATH.'
return 255 return 255
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -231,7 +240,7 @@ env_parallel() {
(_names_of_ALIASES; (_names_of_ALIASES;
_names_of_FUNCTIONS; _names_of_FUNCTIONS;
_names_of_VARIABLES) | _names_of_VARIABLES) |
cat > $HOME/.parallel/ignored_vars cat > "$HOME"/.parallel/ignored_vars
return 0 return 0
fi fi
@ -241,6 +250,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -264,6 +274,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -271,6 +282,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -280,6 +292,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -289,6 +302,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -297,6 +311,7 @@ env_parallel() {
fi fi
unset _variable_NAMES unset _variable_NAMES
# shellcheck disable=SC2006
PARALLEL_ENV="` PARALLEL_ENV="`
$_list_alias_BODIES; $_list_alias_BODIES;
$_list_function_BODIES; $_list_function_BODIES;
@ -309,7 +324,8 @@ env_parallel() {
unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE
unset _remove_bad_NAMES _grep_REGEXP unset _remove_bad_NAMES _grep_REGEXP
unset _prefix_PARALLEL_ENV unset _prefix_PARALLEL_ENV
# Test if environment is too big # Test if environment is too big by running 'true'
# shellcheck disable=SC2006,SC2092
if `_which_PAR true` >/dev/null 2>/dev/null ; then if `_which_PAR true` >/dev/null 2>/dev/null ; then
parallel "$@" parallel "$@"
_parallel_exit_CODE=$? _parallel_exit_CODE=$?
@ -363,13 +379,6 @@ _parset_main() {
# parset "var_a4 var_b4 var_c4" echo ::: {1..3} # parset "var_a4 var_b4 var_c4" echo ::: {1..3}
# echo $var_c4 # echo $var_c4
_make_TEMP() {
# mktemp does not exist on some OS
perl -e 'use File::Temp qw(tempfile);
$ENV{"TMPDIR"} ||= "/tmp";
print((tempfile(DIR=>$ENV{"TMPDIR"}, TEMPLATE => "parXXXXX"))[1])'
}
_parset_NAME="$1" _parset_NAME="$1"
if [ "$_parset_NAME" = "" ] ; then if [ "$_parset_NAME" = "" ] ; then
echo parset: Error: No destination variable given. >&2 echo parset: Error: No destination variable given. >&2
@ -385,6 +394,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -400,45 +410,21 @@ _parset_main() {
return 255 return 255
fi fi
shift shift
echo "$_parset_NAME" |
perl -ne 'chomp;for (split /[, ]/) { # Bash: declare -A myassoc=( )
# Allow: var_32 var[3] # Zsh: typeset -A myassoc=( )
if(not /^[a-zA-Z_][a-zA-Z_0-9]*(\[\d+\])?$/) { # Ksh: typeset -A myassoc=( )
print STDERR "parset: Error: $_ is an invalid variable name.\n"; # shellcheck disable=SC2039,SC2169
print STDERR "parset: Error: Variable names must be letter followed by letters or digits.\n"; if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
print STDERR "parset: Error: Usage:\n"; perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
print STDERR "parset: Error: parset varname GNU Parallel options and command\n"; # This is an associative array
$exitval = 255; # shellcheck disable=SC2006
} eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
} # The eval returns the function!
exit $exitval;
' || return 255
_exit_FILE=`_make_TEMP`
if perl -e 'exit not grep /,| /, @ARGV' "$_parset_NAME" ; then
# $_parset_NAME contains , or space
# Split on , or space to get the names
eval "`
# Compute results into files
($_parset_PARALLEL_PRG --files -k "$@"; echo $? > "$_exit_FILE") |
# var1= cat tmpfile1; rm tmpfile1
# var2= cat tmpfile2; rm tmpfile2
parallel -q echo {2}='\`cat {1}; rm {1}\`' :::: - :::+ \`
echo "$_parset_NAME" |
perl -pe 's/,/ /g'
\`
`"
else else
# $_parset_NAME does not contain , or space # This is a normal array or a list of variable names
# => $_parset_NAME is the name of the array to put data into # shellcheck disable=SC2006
# Supported in: bash zsh ksh mksh eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# Arrays do not work in: sh ash dash # The eval returns the function!
eval "$_parset_NAME=( $(
# Compute results into files. Save exit value
($_parset_PARALLEL_PRG --files -k "$@"; echo $? > "$_exit_FILE") |
perl -pe 'chop;$_="\"\`cat $_; rm $_\`\" "'
) )"
fi fi
unset _parset_NAME _parset_PARALLEL_PRG _parallel_exit_CODE
# Unset _exit_FILE before return
eval "unset _exit_FILE; return \`cat $_exit_FILE; rm $_exit_FILE\`"
} }

View file

@ -27,6 +27,7 @@
# #
# SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=SC2006
env_parallel() { env_parallel() {
# env_parallel.ksh # env_parallel.ksh
@ -64,6 +65,7 @@ env_parallel() {
echo '(_|TIMEOUT|IFS)' echo '(_|TIMEOUT|IFS)'
} }
_ignore_READONLY() { _ignore_READONLY() {
# shellcheck disable=SC1078,SC1079,SC2026
readonly | perl -e '@r = map { readonly | perl -e '@r = map {
chomp; chomp;
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
@ -81,7 +83,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -188,24 +192,27 @@ env_parallel() {
END { exit not $exit }' END { exit not $exit }'
} }
_warning_PAR() { _warning_PAR() {
echo "env_parallel: Warning: $@" >&2 echo "env_parallel: Warning: $*" >&2
} }
_error_PAR() { _error_PAR() {
echo "env_parallel: Error: $@" >&2 echo "env_parallel: Error: $*" >&2
} }
if _which_PAR parallel >/dev/null; then if _which_PAR parallel >/dev/null; then
true parallel found in path true parallel found in path
else else
# shellcheck disable=SC2016
_error_PAR 'parallel must be in $PATH.' _error_PAR 'parallel must be in $PATH.'
return 255 return 255
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -226,6 +233,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -249,6 +257,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -256,6 +265,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -265,6 +275,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -274,6 +285,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -282,6 +294,7 @@ env_parallel() {
fi fi
unset _variable_NAMES unset _variable_NAMES
# shellcheck disable=SC2006
PARALLEL_ENV="` PARALLEL_ENV="`
$_list_alias_BODIES; $_list_alias_BODIES;
$_list_function_BODIES; $_list_function_BODIES;
@ -294,7 +307,8 @@ env_parallel() {
unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE
unset _remove_bad_NAMES _grep_REGEXP unset _remove_bad_NAMES _grep_REGEXP
unset _prefix_PARALLEL_ENV unset _prefix_PARALLEL_ENV
# Test if environment is too big # Test if environment is too big by running 'true'
# shellcheck disable=SC2006,SC2092
if `_which_PAR true` >/dev/null 2>/dev/null ; then if `_which_PAR true` >/dev/null 2>/dev/null ; then
parallel "$@" parallel "$@"
_parallel_exit_CODE=$? _parallel_exit_CODE=$?
@ -363,6 +377,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -382,14 +397,17 @@ _parset_main() {
# Bash: declare -A myassoc=( ) # Bash: declare -A myassoc=( )
# Zsh: typeset -A myassoc=( ) # Zsh: typeset -A myassoc=( )
# Ksh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( )
# shellcheck disable=SC2039,SC2169
if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
# This is an associative array # This is an associative array
eval "`$_parset_PARALLEL_PRG -k --parset assoc,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
else else
# This is a normal array or a list of variable names # This is a normal array or a list of variable names
eval "`$_parset_PARALLEL_PRG -k --parset var,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
fi fi
} }

View file

@ -27,6 +27,7 @@
# #
# SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=SC2006
env_parallel() { env_parallel() {
# env_parallel.mksh # env_parallel.mksh
@ -66,6 +67,7 @@ env_parallel() {
echo '(_)' echo '(_)'
} }
_ignore_READONLY() { _ignore_READONLY() {
# shellcheck disable=SC1078,SC1079,SC2026
readonly | perl -e '@r = map { readonly | perl -e '@r = map {
chomp; chomp;
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
@ -83,7 +85,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -190,24 +194,27 @@ env_parallel() {
END { exit not $exit }' END { exit not $exit }'
} }
_warning_PAR() { _warning_PAR() {
echo "env_parallel: Warning: $@" >&2 echo "env_parallel: Warning: $*" >&2
} }
_error_PAR() { _error_PAR() {
echo "env_parallel: Error: $@" >&2 echo "env_parallel: Error: $*" >&2
} }
if _which_PAR parallel >/dev/null; then if _which_PAR parallel >/dev/null; then
true parallel found in path true parallel found in path
else else
# shellcheck disable=SC2016
_error_PAR 'parallel must be in $PATH.' _error_PAR 'parallel must be in $PATH.'
return 255 return 255
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -228,6 +235,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -251,6 +259,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -258,6 +267,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -267,6 +277,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -276,6 +287,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -284,6 +296,7 @@ env_parallel() {
fi fi
unset _variable_NAMES unset _variable_NAMES
# shellcheck disable=SC2006
PARALLEL_ENV="` PARALLEL_ENV="`
$_list_alias_BODIES; $_list_alias_BODIES;
$_list_function_BODIES; $_list_function_BODIES;
@ -296,7 +309,8 @@ env_parallel() {
unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE
unset _remove_bad_NAMES _grep_REGEXP unset _remove_bad_NAMES _grep_REGEXP
unset _prefix_PARALLEL_ENV unset _prefix_PARALLEL_ENV
# Test if environment is too big # Test if environment is too big by running 'true'
# shellcheck disable=SC2006,SC2092
if `_which_PAR true` >/dev/null 2>/dev/null ; then if `_which_PAR true` >/dev/null 2>/dev/null ; then
parallel "$@" parallel "$@"
_parallel_exit_CODE=$? _parallel_exit_CODE=$?
@ -365,6 +379,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -384,14 +399,17 @@ _parset_main() {
# Bash: declare -A myassoc=( ) # Bash: declare -A myassoc=( )
# Zsh: typeset -A myassoc=( ) # Zsh: typeset -A myassoc=( )
# Ksh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( )
# shellcheck disable=SC2039,SC2169
if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
# This is an associative array # This is an associative array
eval "`$_parset_PARALLEL_PRG -k --parset assoc,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
else else
# This is a normal array or a list of variable names # This is a normal array or a list of variable names
eval "`$_parset_PARALLEL_PRG -k --parset var,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
fi fi
} }

View file

@ -79,7 +79,7 @@ env_parallel() {
} }
_ignore_HARDCODED() { _ignore_HARDCODED() {
# These names cannot be detected # These names cannot be detected
echo '(_|TIMEOUT)' echo '(_|TIMEOUT|IFS)'
} }
_ignore_READONLY() { _ignore_READONLY() {
# shellcheck disable=SC1078,SC1079,SC2026 # shellcheck disable=SC1078,SC1079,SC2026
@ -88,7 +88,8 @@ env_parallel() {
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
# ash: readonly var='val' # ash: readonly var='val'
# ksh: var='val' # ksh: var='val'
s/^(readonly )?([^= ]*)(=.*|)$/$2/ or # mksh: PIPESTATUS[0]
s/^(readonly )?([^=\[ ]*?)(\[\d+\])?(=.*|)$/$2/ or
# bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4") # bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4")
# zsh: typeset -r var='val' # zsh: typeset -r var='val'
s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/; s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/;
@ -99,7 +100,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -221,10 +224,12 @@ env_parallel() {
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -245,6 +250,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -268,6 +274,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -275,6 +282,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -284,6 +292,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -293,6 +302,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -301,6 +311,7 @@ env_parallel() {
fi fi
unset _variable_NAMES unset _variable_NAMES
# shellcheck disable=SC2006
PARALLEL_ENV="` PARALLEL_ENV="`
$_list_alias_BODIES; $_list_alias_BODIES;
$_list_function_BODIES; $_list_function_BODIES;
@ -313,8 +324,8 @@ env_parallel() {
unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE
unset _remove_bad_NAMES _grep_REGEXP unset _remove_bad_NAMES _grep_REGEXP
unset _prefix_PARALLEL_ENV unset _prefix_PARALLEL_ENV
# Test if environment is too big # Test if environment is too big by running 'true'
# shellcheck disable=SC2092 # shellcheck disable=SC2006,SC2092
if `_which_PAR true` >/dev/null 2>/dev/null ; then if `_which_PAR true` >/dev/null 2>/dev/null ; then
parallel "$@" parallel "$@"
_parallel_exit_CODE=$? _parallel_exit_CODE=$?
@ -368,13 +379,6 @@ _parset_main() {
# parset "var_a4 var_b4 var_c4" echo ::: {1..3} # parset "var_a4 var_b4 var_c4" echo ::: {1..3}
# echo $var_c4 # echo $var_c4
_make_TEMP() {
# mktemp does not exist on some OS
perl -e 'use File::Temp qw(tempfile);
$ENV{"TMPDIR"} ||= "/tmp";
print((tempfile(DIR=>$ENV{"TMPDIR"}, TEMPLATE => "parXXXXX"))[1])'
}
_parset_NAME="$1" _parset_NAME="$1"
if [ "$_parset_NAME" = "" ] ; then if [ "$_parset_NAME" = "" ] ; then
echo parset: Error: No destination variable given. >&2 echo parset: Error: No destination variable given. >&2
@ -390,6 +394,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -405,46 +410,21 @@ _parset_main() {
return 255 return 255
fi fi
shift shift
echo "$_parset_NAME" |
perl -ne 'chomp;for (split /[, ]/) { # Bash: declare -A myassoc=( )
# Allow: var_32 var[3] # Zsh: typeset -A myassoc=( )
if(not /^[a-zA-Z_][a-zA-Z_0-9]*(\[\d+\])?$/) { # Ksh: typeset -A myassoc=( )
print STDERR "parset: Error: $_ is an invalid variable name.\n"; # shellcheck disable=SC2039,SC2169
print STDERR "parset: Error: Variable names must be letter followed by letters or digits.\n"; if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
print STDERR "parset: Error: Usage:\n"; perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
print STDERR "parset: Error: parset varname GNU Parallel options and command\n"; # This is an associative array
$exitval = 255; # shellcheck disable=SC2006
} eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
} # The eval returns the function!
exit $exitval;
' || return 255
_exit_FILE=`_make_TEMP`
if perl -e 'exit not grep /,| /, @ARGV' "$_parset_NAME" ; then
# $_parset_NAME contains , or space
# Split on , or space to get the names
# shellcheck disable=SC2016,SC2046
eval "`
# Compute results into files
($_parset_PARALLEL_PRG --files -k "$@"; echo $? > "$_exit_FILE") |
# var1= cat tmpfile1; rm tmpfile1
# var2= cat tmpfile2; rm tmpfile2
parallel --plain -q echo '{2}=\`cat {1}; rm {1}\`' :::: - :::+ \`
echo "$_parset_NAME" |
perl -pe 's/,/ /g'
\`
`"
else else
# $_parset_NAME does not contain , or space # This is a normal array or a list of variable names
# => $_parset_NAME is the name of the array to put data into # shellcheck disable=SC2006
# Supported in: bash zsh ksh mksh eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# Arrays do not work in: sh ash dash # The eval returns the function!
eval "$_parset_NAME=( $(
# Compute results into files. Save exit value
($_parset_PARALLEL_PRG --files -k "$@"; echo $? > "$_exit_FILE") |
perl -pe 'chop;$_="\"\`cat $_; rm $_\`\" "'
) )"
fi fi
unset _parset_NAME _parset_PARALLEL_PRG _parallel_exit_CODE
# Unset _exit_FILE before return
eval "unset _exit_FILE; return \`cat $_exit_FILE; rm $_exit_FILE\`"
} }

View file

@ -27,6 +27,7 @@
# #
# SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-FileCopyrightText: 2021-2022 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=SC2006
env_parallel() { env_parallel() {
# env_parallel.zsh # env_parallel.zsh
@ -62,7 +63,8 @@ env_parallel() {
# sh on UnixWare: readonly TIMEOUT # sh on UnixWare: readonly TIMEOUT
# ash: readonly var='val' # ash: readonly var='val'
# ksh: var='val' # ksh: var='val'
s/^(readonly )?([^= ]*)(=.*|)$/$2/ or # mksh: PIPESTATUS[0]
s/^(readonly )?([^=\[ ]*?)(\[\d+\])?(=.*|)$/$2/ or
# bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4") # bash: declare -ar BASH_VERSINFO=([0]="4" [1]="4")
# zsh: typeset -r var='val' # zsh: typeset -r var='val'
s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/; s/^\S+\s+\S+\s+(\S[^=]*)(=.*|$)/$1/;
@ -73,7 +75,9 @@ env_parallel() {
} }
_remove_bad_NAMES() { _remove_bad_NAMES() {
# Do not transfer vars and funcs from env_parallel # Do not transfer vars and funcs from env_parallel
# shellcheck disable=SC2006
_ignore_RO="`_ignore_READONLY`" _ignore_RO="`_ignore_READONLY`"
# shellcheck disable=SC2006
_ignore_HARD="`_ignore_HARDCODED`" _ignore_HARD="`_ignore_HARDCODED`"
# Macos-grep does not like long patterns # Macos-grep does not like long patterns
# Old Solaris grep does not support -E # Old Solaris grep does not support -E
@ -180,24 +184,27 @@ env_parallel() {
END { exit not $exit }' END { exit not $exit }'
} }
_warning_PAR() { _warning_PAR() {
echo "env_parallel: Warning: $@" >&2 echo "env_parallel: Warning: $*" >&2
} }
_error_PAR() { _error_PAR() {
echo "env_parallel: Error: $@" >&2 echo "env_parallel: Error: $*" >&2
} }
if _which_PAR parallel >/dev/null; then if _which_PAR parallel >/dev/null; then
true parallel found in path true parallel found in path
else else
# shellcheck disable=SC2016
_error_PAR 'parallel must be in $PATH.' _error_PAR 'parallel must be in $PATH.'
return 255 return 255
fi fi
# Grep regexp for vars given by --env # Grep regexp for vars given by --env
# shellcheck disable=SC2006
_grep_REGEXP="`_make_grep_REGEXP \"$@\"`" _grep_REGEXP="`_make_grep_REGEXP \"$@\"`"
unset _make_grep_REGEXP unset _make_grep_REGEXP
# Deal with --env _ # Deal with --env _
# shellcheck disable=SC2006
_ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`" _ignore_UNDERSCORE="`_get_ignored_VARS \"$@\"`"
unset _get_ignored_VARS unset _get_ignored_VARS
@ -218,6 +225,7 @@ env_parallel() {
else else
# Insert ::: between each level of session # Insert ::: between each level of session
# so you can pop off the last ::: at --end-session # so you can pop off the last ::: at --end-session
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\"; PARALLEL_IGNORED_NAMES="`echo \"$PARALLEL_IGNORED_NAMES\";
echo :::; echo :::;
(_names_of_ALIASES; (_names_of_ALIASES;
@ -241,6 +249,7 @@ env_parallel() {
true skip true skip
else else
# Pop off last ::: from PARALLEL_IGNORED_NAMES # Pop off last ::: from PARALLEL_IGNORED_NAMES
# shellcheck disable=SC2006
PARALLEL_IGNORED_NAMES="`perl -e ' PARALLEL_IGNORED_NAMES="`perl -e '
$ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s; $ENV{PARALLEL_IGNORED_NAMES} =~ s/(.*):::.*?$/$1/s;
print $ENV{PARALLEL_IGNORED_NAMES} print $ENV{PARALLEL_IGNORED_NAMES}
@ -248,6 +257,7 @@ env_parallel() {
return 0 return 0
fi fi
# Grep alias names # Grep alias names
# shellcheck disable=SC2006
_alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`" _alias_NAMES="`_names_of_ALIASES | _remove_bad_NAMES | xargs echo`"
_list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES" _list_alias_BODIES="_bodies_of_ALIASES $_alias_NAMES"
if [ "$_alias_NAMES" = "" ] ; then if [ "$_alias_NAMES" = "" ] ; then
@ -257,6 +267,7 @@ env_parallel() {
unset _alias_NAMES unset _alias_NAMES
# Grep function names # Grep function names
# shellcheck disable=SC2006
_function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`" _function_NAMES="`_names_of_FUNCTIONS | _remove_bad_NAMES | xargs echo`"
_list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES" _list_function_BODIES="_bodies_of_FUNCTIONS $_function_NAMES"
if [ "$_function_NAMES" = "" ] ; then if [ "$_function_NAMES" = "" ] ; then
@ -266,6 +277,7 @@ env_parallel() {
unset _function_NAMES unset _function_NAMES
# Grep variable names # Grep variable names
# shellcheck disable=SC2006
_variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`" _variable_NAMES="`_names_of_VARIABLES | _remove_bad_NAMES | xargs echo`"
_list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES" _list_variable_VALUES="_bodies_of_VARIABLES $_variable_NAMES"
if [ "$_variable_NAMES" = "" ] ; then if [ "$_variable_NAMES" = "" ] ; then
@ -274,6 +286,7 @@ env_parallel() {
fi fi
unset _variable_NAMES unset _variable_NAMES
# shellcheck disable=SC2006
PARALLEL_ENV="` PARALLEL_ENV="`
eval $_list_alias_BODIES; eval $_list_alias_BODIES;
eval $_list_function_BODIES; eval $_list_function_BODIES;
@ -286,7 +299,8 @@ env_parallel() {
unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE
unset _remove_bad_NAMES _grep_REGEXP unset _remove_bad_NAMES _grep_REGEXP
unset _prefix_PARALLEL_ENV unset _prefix_PARALLEL_ENV
# Test if environment is too big # Test if environment is too big by running 'true'
# shellcheck disable=SC2006,SC2092
if `_which_PAR true` >/dev/null 2>/dev/null ; then if `_which_PAR true` >/dev/null 2>/dev/null ; then
parallel "$@" parallel "$@"
_parallel_exit_CODE=$? _parallel_exit_CODE=$?
@ -355,6 +369,7 @@ _parset_main() {
return 255 return 255
fi fi
if [ "$_parset_NAME" = "--version" ] ; then if [ "$_parset_NAME" = "--version" ] ; then
# shellcheck disable=SC2006
echo "parset 20220323 (GNU parallel `parallel --minversion 1`)" echo "parset 20220323 (GNU parallel `parallel --minversion 1`)"
echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software" echo "Copyright (C) 2007-2022 Ole Tange, http://ole.tange.dk and Free Software"
echo "Foundation, Inc." echo "Foundation, Inc."
@ -374,14 +389,17 @@ _parset_main() {
# Bash: declare -A myassoc=( ) # Bash: declare -A myassoc=( )
# Zsh: typeset -A myassoc=( ) # Zsh: typeset -A myassoc=( )
# Ksh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( )
# shellcheck disable=SC2039,SC2169
if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | if (typeset -p "$_parset_NAME" 2>/dev/null; echo) |
perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then
# This is an associative array # This is an associative array
eval "`$_parset_PARALLEL_PRG -k --parset assoc,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset assoc,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
else else
# This is a normal array or a list of variable names # This is a normal array or a list of variable names
eval "`$_parset_PARALLEL_PRG -k --parset var,"$_parset_NAME" "$@"`" # shellcheck disable=SC2006
eval "`$_parset_PARALLEL_PRG -k --_parset var,"$_parset_NAME" "$@"`"
# The eval returns the function! # The eval returns the function!
fi fi
} }

View file

@ -1555,25 +1555,27 @@ sub acquire_semaphore() {
sub __PARSE_OPTIONS__() {} sub __PARSE_OPTIONS__() {}
sub shell_completion() { sub shell_completion() {
if($opt::completion eq "zsh") { if($opt::shellcompletion eq "zsh") {
# if(shell == zsh); # if shell == zsh
zsh_competion(); zsh_competion();
} elsif($opt::completion eq "bash") { } elsif($opt::shellcompletion eq "bash") {
# if(shell == bash); # if shell == bash
bash_competion(); bash_competion();
} elsif($opt::completion eq "auto") { } elsif($opt::shellcompletion eq "auto") {
if($Global::shell =~ m:/zsh$|^zsh$:) { if($Global::shell =~ m:/zsh$|^zsh$:) {
# if(shell == zsh); # if shell == zsh
zsh_competion(); zsh_competion();
} elsif($Global::shell =~ m:/bash$|^bash$:) { } elsif($Global::shell =~ m:/bash$|^bash$:) {
# if(shell == bash); # if shell == bash
bash_competion(); bash_competion();
} else { } else {
::error("--completion is not implemented for '$Global::shell'."); ::error("--shellcompletion is not implemented for ".
"'$Global::shell'.");
wait_and_exit(255); wait_and_exit(255);
} }
} else { } else {
::error("--completion is not implemented for '$opt::completion'."); ::error("--shellcompletion is not implemented for ".
"'$opt::shellcompletion'.");
wait_and_exit(255); wait_and_exit(255);
} }
} }
@ -1600,10 +1602,14 @@ sub bash_competion() {
my $func = $4; my $func = $4;
# opt=s => opt # opt=s => opt
$opt =~ s/[:=].$//; $opt =~ s/[:=].$//;
push @bash_completion, if($opt =~ /^_/) {
(map { (length $_ == 1) ? "-$_ " : "--$_ " } # internal options start with --_
split /\|/, $opt); # skip
} else {
push @bash_completion,
(map { (length $_ == 1) ? "-$_ " : "--$_ " }
split /\|/, $opt);
}
} }
shift @och; shift @och;
} }
@ -1630,15 +1636,20 @@ sub zsh_competion() {
my $func = $4; my $func = $4;
# opt=s => opt # opt=s => opt
$opt =~ s/[:=].$//; $opt =~ s/[:=].$//;
# {-o,--option} if($opt =~ /^_/) {
my $zsh_opt = join(",", # internal options start with --_
(map { (length $_ == 1) ? "-$_" : "--$_" } # skip
split /\|/, $opt)); } else {
if($zsh_opt =~ /,/) { $zsh_opt = "{$zsh_opt}"; } # {-o,--option}
$desc =~ s/'/'"'"'/g; my $zsh_opt = join(",",
$argdesc =~ s/'/'"'"'/g; (map { (length $_ == 1) ? "-$_" : "--$_" }
$func =~ s/'/'"'"'/g; split /\|/, $opt));
push @zsh_completion, $zsh_opt."'".$desc.$argdesc.$func."' "; if($zsh_opt =~ /,/) { $zsh_opt = "{$zsh_opt}"; }
$desc =~ s/'/'"'"'/g;
$argdesc =~ s/'/'"'"'/g;
$func =~ s/'/'"'"'/g;
push @zsh_completion, $zsh_opt."'".$desc.$argdesc.$func."' ";
}
} }
shift @och; shift @och;
} }
@ -1857,9 +1868,12 @@ sub options_completion_hash() {
"[Use sep-str instead of ::: as separator string]:sep-str" "[Use sep-str instead of ::: as separator string]:sep-str"
=> \$opt::arg_sep), => \$opt::arg_sep),
("arg-file-sep|argfilesep=s". ("arg-file-sep|argfilesep=s".
"[Use sep-str instead of :::: as separator string between command and argument files]:sep-str" "[Use sep-str instead of :::: as separator string ".
"between command and argument files]:sep-str"
=> \$opt::arg_file_sep), => \$opt::arg_file_sep),
("trim=s[Trim white space in input]:trim_method:(n l r lr rl)" ('trim=s[Trim white space in input]:trim_method:'.
'((n\:"No trim" l\:"Left\ trim" r\:"Right trim" '.
'lr\:"Both trim" rl\:"Both trim"))'
=> \$opt::trim), => \$opt::trim),
"env=s[Copy environment variable var]:var:_vars" => \@opt::env, "env=s[Copy environment variable var]:var:_vars" => \@opt::env,
"recordenv|record-env[Record environment]" => \$opt::record_env, "recordenv|record-env[Record environment]" => \$opt::record_env,
@ -1961,11 +1975,11 @@ sub options_completion_hash() {
("shebang|hashbang". ("shebang|hashbang".
"[GNU parallel can be called as a shebang (#!) command as the first line of a script. The content of the file will be treated as inputsource]" "[GNU parallel can be called as a shebang (#!) command as the first line of a script. The content of the file will be treated as inputsource]"
=> \$opt::shebang), => \$opt::shebang),
("internal-pipe-means-argfiles|internalpipemeansargfiles" ("_pipe-means-argfiles[internal]"
=> \$opt::internal_pipe_means_argfiles), => \$opt::_pipe_means_argfiles),
"Y" => \$opt::retired, "Y" => \$opt::retired,
("skip-first-line|skipfirstline". ("skip-first-line|skipfirstline".
"[Do not use the first line of input (used by GNU parallel itself when called with --shebang)]" "[Do not use the first line of input]"
=> \$opt::skip_first_line), => \$opt::skip_first_line),
"bug" => \$opt::bug, "bug" => \$opt::bug,
# --pipe # --pipe
@ -1979,7 +1993,7 @@ sub options_completion_hash() {
"[Split record between endstring and startstring]:endstring" "[Split record between endstring and startstring]:endstring"
=> \$opt::recend), => \$opt::recend),
("regexp|regex". ("regexp|regex".
"[Use --regexp to interpret --recstart and --recend as regular expressions]" "[Interpret --recstart and --recend as regular expressions]"
=> \$opt::regexp), => \$opt::regexp),
("remove-rec-sep|removerecsep|rrs". ("remove-rec-sep|removerecsep|rrs".
"[Remove record separator]" => \$opt::remove_rec_sep), "[Remove record separator]" => \$opt::remove_rec_sep),
@ -2010,10 +2024,12 @@ sub options_completion_hash() {
"embed[Embed GNU parallel in a shell script]" => \$opt::embed, "embed[Embed GNU parallel in a shell script]" => \$opt::embed,
("filter=s[Only run jobs where filter is true]:filter" ("filter=s[Only run jobs where filter is true]:filter"
=> \@opt::filter), => \@opt::filter),
"parset=s" => \$opt::parset, "_parset=s[Generate shell code for parset]" => \$opt::_parset,
"completion=s" => \$opt::completion, ("shell-completion|shellcompletion=s".
"[Generate shell code for shell completion]"
=> \$opt::shellcompletion),
# Parameter for testing optimal values # Parameter for testing optimal values
"test=s" => \$opt::test, "_test=s" => \$opt::_test,
); );
} }
@ -2061,7 +2077,7 @@ sub get_options_from_array($@) {
sub parse_parset() { sub parse_parset() {
$Global::progname = "parset"; $Global::progname = "parset";
@Global::parset_vars = split /[ ,]/, $opt::parset; @Global::parset_vars = split /[ ,]/, $opt::_parset;
my $var_or_assoc = shift @Global::parset_vars; my $var_or_assoc = shift @Global::parset_vars;
# Legal names: var _v2ar arrayentry[2] # Legal names: var _v2ar arrayentry[2]
my @illegal = (grep { not /^[a-zA-Z_][a-zA-Z_0-9]*(\[\d+\])?$/ } my @illegal = (grep { not /^[a-zA-Z_][a-zA-Z_0-9]*(\[\d+\])?$/ }
@ -2089,7 +2105,7 @@ sub parse_parset() {
$Global::parset_endstring=")\n"; $Global::parset_endstring=")\n";
} }
} else { } else {
::die_bug("parset: unknown '$opt::parset'"); ::die_bug("parset: unknown '$opt::_parset'");
} }
} }
@ -2122,7 +2138,7 @@ sub parse_options(@) {
} }
::debug("init","Global::shell $Global::shell\n"); ::debug("init","Global::shell $Global::shell\n");
$Global::cshell = $Global::shell =~ m:(/[-a-z]*)?csh:; $Global::cshell = $Global::shell =~ m:(/[-a-z]*)?csh:;
if(defined $opt::parset) { parse_parset(); } if(defined $opt::_parset) { parse_parset(); }
if(defined $opt::X) { $Global::ContextReplace = 1; } if(defined $opt::X) { $Global::ContextReplace = 1; }
if(defined $opt::silent) { $Global::verbose = 0; } if(defined $opt::silent) { $Global::verbose = 0; }
if(defined $opt::null) { $/ = "\0"; } if(defined $opt::null) { $/ = "\0"; }
@ -2172,7 +2188,7 @@ sub parse_options(@) {
# Default: Same nice level as GNU Parallel is started at # Default: Same nice level as GNU Parallel is started at
$opt::nice ||= eval { getpriority(0,0) } || 0; $opt::nice ||= eval { getpriority(0,0) } || 0;
if(defined $opt::help) { usage(); exit(0); } if(defined $opt::help) { usage(); exit(0); }
if(defined $opt::completion) { shell_completion(); exit(0); } if(defined $opt::shellcompletion) { shell_completion(); exit(0); }
if(defined $opt::embed) { embed(); exit(0); } if(defined $opt::embed) { embed(); exit(0); }
if(defined $opt::sqlandworker) { if(defined $opt::sqlandworker) {
$opt::sqlmaster = $opt::sqlworker = $opt::sqlandworker; $opt::sqlmaster = $opt::sqlworker = $opt::sqlandworker;
@ -3162,7 +3178,7 @@ sub read_options() {
} }
my $script = Q(shift @ARGV); my $script = Q(shift @ARGV);
# exec myself to split $ARGV[0] into separate fields # exec myself to split $ARGV[0] into separate fields
exec "$0 --internal-pipe-means-argfiles @options @parser $script ". exec "$0 --_pipe-means-argfiles @options @parser $script ".
"::: @ARGV"; "::: @ARGV";
} }
} }
@ -3273,7 +3289,7 @@ sub read_args_from_command_line() {
# Uses: # Uses:
# $Global::arg_sep # $Global::arg_sep
# $Global::arg_file_sep # $Global::arg_file_sep
# $opt::internal_pipe_means_argfiles # $opt::_pipe_means_argfiles
# $opt::pipe # $opt::pipe
# @opt::a # @opt::a
# Returns: # Returns:
@ -3317,7 +3333,7 @@ sub read_args_from_command_line() {
push @opt::linkinputsource, $is_linked; push @opt::linkinputsource, $is_linked;
} }
if($is_file if($is_file
or ($opt::internal_pipe_means_argfiles and $opt::pipe) or ($opt::_pipe_means_argfiles and $opt::pipe)
) { ) {
# Group of file names on the command line. # Group of file names on the command line.
# Append args into -a # Append args into -a
@ -5374,7 +5390,7 @@ sub wait_and_exit($) {
# Avoid: Warning: unable to close filehandle properly: No space # Avoid: Warning: unable to close filehandle properly: No space
# left on device during global destruction. # left on device during global destruction.
$SIG{__WARN__} = sub {}; $SIG{__WARN__} = sub {};
if($opt::parset) { if($opt::_parset) {
# Make the shell script return $error # Make the shell script return $error
print "$Global::parset_endstring\nreturn $error"; print "$Global::parset_endstring\nreturn $error";
} }
@ -10485,9 +10501,9 @@ sub start($) {
$ENV{'PARALLEL_TMP'} = ::tmpname("par"); $ENV{'PARALLEL_TMP'} = ::tmpname("par");
$job->add_rm($ENV{'PARALLEL_TMP'}); $job->add_rm($ENV{'PARALLEL_TMP'});
$job->fill_templates(); $job->fill_templates();
$ENV{'SSHPASS'} = $job->{'sshlogin'}->{'password'};
::debug("run", $Global::total_running, " processes . Starting (", ::debug("run", $Global::total_running, " processes . Starting (",
$job->seq(), "): $command\n"); $job->seq(), "): $command\n");
$ENV{'SSHPASS'} = $job->{'sshlogin'}->{'password'};
if($opt::pipe) { if($opt::pipe) {
my ($stdin_fh) = ::gensym(); my ($stdin_fh) = ::gensym();
$pid = open3_setpgrp($stdin_fh,$stdout_fh,$stderr_fh,$command); $pid = open3_setpgrp($stdin_fh,$stdout_fh,$stderr_fh,$command);

View file

@ -774,20 +774,6 @@ https://perldoc.perl.org/perlre.html
See also: B<--csv> B<{>I<n>B<}> B<--trim> B<--link> See also: B<--csv> B<{>I<n>B<}> B<--trim> B<--link>
=item B<--completion> I<shell> (alpha testing)
Generate shell completion code for interactive shells.
Supported shells: bash zsh.
Use I<auto> as I<shell> to automatically detect running shell.
Activate the completion code with:
zsh% eval "`parallel --completion auto`"
bash$ eval "`parallel --completion auto`"
=item B<--compress> =item B<--compress>
Compress temporary files. Compress temporary files.
@ -2025,6 +2011,17 @@ from the terminal. Only run the command line if the response starts
with 'y' or 'Y'. Implies B<-t>. with 'y' or 'Y'. Implies B<-t>.
=item B<--_parset> I<type>,I<varname>
Used internally by B<parset>.
Generate shell code to be eval'ed which will set the variable(s)
I<varname>. I<type> can be 'assoc' for associative array or 'var' for
normal variables.
The only supported use is as part of B<parset>.
=item B<--parens> I<parensstring> =item B<--parens> I<parensstring>
Use I<parensstring> instead of B<{==}>. Use I<parensstring> instead of B<{==}>.
@ -2788,6 +2785,29 @@ B<--shebang-wrap> must be set as the first option.
See also: B<--shebang> See also: B<--shebang>
=item B<--shell-completion> I<shell> (alpha testing)
Generate shell completion code for interactive shells.
Supported shells: bash zsh.
Use I<auto> as I<shell> to automatically detect running shell.
Activate the completion code with:
zsh% eval "$(parallel --shell-completion auto)"
bash$ eval "$(parallel --shell-completion auto)"
Or put this `/usr/share/zsh/site-functions/_parallel`, then `compinit`
to generate `~/.zcompdump`:
#compdef parallel
(( $+functions[_comp_parallel] )) ||
eval "$(parallel --shell-completion auto)" &&
_comp_parallel
=item B<--shell-quote> =item B<--shell-quote>
Does not run the command but quotes it. Useful for making quoted Does not run the command but quotes it. Useful for making quoted

View file

@ -16,13 +16,13 @@ export -f stdsort
# Test amount of parallelization # Test amount of parallelization
# parallel --shuf --jl /tmp/myjl -j1 'export JOBS={1};'bash tests-to-run/parallel-local-0.3s.sh ::: {1..16} ::: {1..5} # parallel --shuf --jl /tmp/myjl -j1 'export JOBS={1};'bash tests-to-run/parallel-local-0.3s.sh ::: {1..16} ::: {1..5}
par_completion() { par_shellcompletion() {
echo '### --completion' echo '### --shellcompletion'
# This will change, if you change options # This will change, if you change options
parallel --completion bash | md5sum parallel --shellcompletion bash | md5sum
bash -c 'parallel --completion auto;true' | md5sum bash -c 'parallel --shellcompletion auto;true' | md5sum
parallel --completion zsh | md5sum parallel --shellcompletion zsh | md5sum
zsh -c 'parallel --completion auto;true' | md5sum zsh -c 'parallel --shellcompletion auto;true' | md5sum
} }
par_ctagstring() { par_ctagstring() {

View file

@ -20,7 +20,7 @@ par_reload_slf_every_second() {
# This used to take 20 seconds (version 20220322) because the # This used to take 20 seconds (version 20220322) because the
# updated --slf would only read after first job finished # updated --slf would only read after first job finished
seq 3 | seq 3 |
stdout /usr/bin/time -f %e parallel-20220322 --slf "$tmp" 'true {};sleep 10' | stdout /usr/bin/time -f %e parallel --slf "$tmp" 'true {};sleep 10' |
perl -ne '$_ < 20 and print "OK\n"' perl -ne '$_ < 20 and print "OK\n"'
rm "$tmp" rm "$tmp"
} }

View file

@ -699,9 +699,7 @@ par_bash_underscore() {
echo "OK if no myfunc ^^^^^^^^^^^^^^^^^^^^^^^^^" >&2; echo "OK if no myfunc ^^^^^^^^^^^^^^^^^^^^^^^^^" >&2;
_EOF _EOF
) )
stdout ssh bash@lo "$myscript" | stdout ssh bash@lo "$myscript"
perl -pe 's/line ..:/line XX:/;
s@environment:@/bin/bash:@;'
} }
par_csh_underscore() { par_csh_underscore() {
@ -844,8 +842,7 @@ _EOF
# Old versions of fish sometimes throw up bugs all over, # Old versions of fish sometimes throw up bugs all over,
# but seem to work OK otherwise. So ignore these errors. # but seem to work OK otherwise. So ignore these errors.
ssh fish@lo "$myscript" 2>&1 | ssh fish@lo "$myscript" 2>&1 |
perl -ne '/fish:|fish\(/ and next; print' | perl -ne '/fish:|fish\(/ and next; print'
perl -pe 's:/tmp/par.....:script:'
} }
par_ksh_underscore() { par_ksh_underscore() {
@ -1871,7 +1868,7 @@ par_ksh_environment_too_big() {
echo 'bug #50815: env_parallel should warn if the environment is too big' echo 'bug #50815: env_parallel should warn if the environment is too big'
len_functions=-$(functions|wc -c)/1000 len_functions=-$(functions|wc -c)/1000
len_variables=-$(typeset -p | wc -c)/1000 len_variables=-$(typeset -p | wc -c)/1000
len_var=$len_variables+45 len_var=$len_variables+40
len_var_remote=$len_variables+30 len_var_remote=$len_variables+30
len_var_quote=$len_variables+43 len_var_quote=$len_variables+43
len_var_quote_remote=$len_variables+30 len_var_quote_remote=$len_variables+30
@ -2941,8 +2938,7 @@ par_fish_env_parallel_session() {
set -e PARALLEL_IGNORED_NAMES set -e PARALLEL_IGNORED_NAMES
_EOF _EOF
) )
ssh fish@lo "$myscript" 2>&1 | ssh fish@lo "$myscript" 2>&1
perl -pe 's:/tmp/par.....:script:g'
} }
par_ksh_env_parallel_session() { par_ksh_env_parallel_session() {
@ -3332,6 +3328,6 @@ compgen -A function | grep par_ | LC_ALL=C sort -r |
s/sh\[\d+\]/sh[XXX]/; s/sh\[\d+\]/sh[XXX]/;
s/.*(tange|zenodo).*//i; s/.*(tange|zenodo).*//i;
s:/usr/bin:/bin:g; s:/usr/bin:/bin:g;
s:/tmp/par.....\[\d+\]:script[9]:g; s:/tmp/par-job-\d+_.....\[\d+\]:script[9]:g;
s!/tmp/par.....:!script:!g; s!/tmp/par-job-\d+_.....!script!g;
' '

View file

@ -62,11 +62,6 @@ par_colsep_0 OK
par_colsep_0 OK par_colsep_0 OK
par_colsep_default bug #37956: --colsep does not default to '\t' as specified in the man page. par_colsep_default bug #37956: --colsep does not default to '\t' as specified in the man page.
par_colsep_default one 1 par_colsep_default one 1
par_completion ### --completion
par_completion 857e87c031164f28c4ec91e610c8cff7 -
par_completion 857e87c031164f28c4ec91e610c8cff7 -
par_completion 09b6d6d121bc9542589aca39741e5390 -
par_completion 09b6d6d121bc9542589aca39741e5390 -
par_compress_stdout_stderr ### Test compress - stdout par_compress_stdout_stderr ### Test compress - stdout
par_compress_stdout_stderr OK par_compress_stdout_stderr OK
par_compress_stdout_stderr ### Test compress - stderr par_compress_stdout_stderr ### Test compress - stderr
@ -954,6 +949,11 @@ par_rpl_that_is_substring_of_longer_rpl a.b/c.d/e.f=a.b/c.d/e.f
par_sem_quote ### sem --quote should not add empty argument par_sem_quote ### sem --quote should not add empty argument
par_sem_quote echo par_sem_quote echo
par_sem_quote par_sem_quote
par_shellcompletion ### --shellcompletion
par_shellcompletion b0347a540d9fd8a81339b79577be4567 -
par_shellcompletion b0347a540d9fd8a81339b79577be4567 -
par_shellcompletion 5b279fc707895c822a66e84b32b47195 -
par_shellcompletion 5b279fc707895c822a66e84b32b47195 -
par_slow_pipe_regexp ### bug #53718: --pipe --regexp -N blocks par_slow_pipe_regexp ### bug #53718: --pipe --regexp -N blocks
par_slow_pipe_regexp This should take a few ms, but took more than 2 hours par_slow_pipe_regexp This should take a few ms, but took more than 2 hours
par_slow_pipe_regexp 0 1 1 par_slow_pipe_regexp 0 1 1

View file

@ -659,25 +659,25 @@ par_sh_env_parallel_session /bin/sh: XXX: level2alias: not found
par_sh_env_parallel_session /bin/sh: XXX: Bad substitution par_sh_env_parallel_session /bin/sh: XXX: Bad substitution
par_sh_env_parallel_session ### level0+1+2 should be transferred par_sh_env_parallel_session ### level0+1+2 should be transferred
par_sh_env_parallel_session l0var par_sh_env_parallel_session l0var
par_sh_env_parallel_session script: 29: level0func: not found par_sh_env_parallel_session script: 27: level0func: not found
par_sh_env_parallel_session script: 29: level0alias: not found par_sh_env_parallel_session script: 27: level0alias: not found
par_sh_env_parallel_session script: 29: Bad substitution par_sh_env_parallel_session script: 27: Bad substitution
par_sh_env_parallel_session l0var par_sh_env_parallel_session l0var
par_sh_env_parallel_session /bin/sh: XXX: level0func: not found par_sh_env_parallel_session /bin/sh: XXX: level0func: not found
par_sh_env_parallel_session /bin/sh: XXX: level0alias: not found par_sh_env_parallel_session /bin/sh: XXX: level0alias: not found
par_sh_env_parallel_session /bin/sh: XXX: Bad substitution par_sh_env_parallel_session /bin/sh: XXX: Bad substitution
par_sh_env_parallel_session l1var par_sh_env_parallel_session l1var
par_sh_env_parallel_session script: 29: level1func: not found par_sh_env_parallel_session script: 27: level1func: not found
par_sh_env_parallel_session script: 29: level1alias: not found par_sh_env_parallel_session script: 27: level1alias: not found
par_sh_env_parallel_session script: 29: Bad substitution par_sh_env_parallel_session script: 27: Bad substitution
par_sh_env_parallel_session l1var par_sh_env_parallel_session l1var
par_sh_env_parallel_session /bin/sh: XXX: level1func: not found par_sh_env_parallel_session /bin/sh: XXX: level1func: not found
par_sh_env_parallel_session /bin/sh: XXX: level1alias: not found par_sh_env_parallel_session /bin/sh: XXX: level1alias: not found
par_sh_env_parallel_session /bin/sh: XXX: Bad substitution par_sh_env_parallel_session /bin/sh: XXX: Bad substitution
par_sh_env_parallel_session l2var par_sh_env_parallel_session l2var
par_sh_env_parallel_session script: 29: level2func: not found par_sh_env_parallel_session script: 27: level2func: not found
par_sh_env_parallel_session script: 29: level2alias: not found par_sh_env_parallel_session script: 27: level2alias: not found
par_sh_env_parallel_session script: 29: Bad substitution par_sh_env_parallel_session script: 27: Bad substitution
par_sh_env_parallel_session l2var par_sh_env_parallel_session l2var
par_sh_env_parallel_session /bin/sh: XXX: level2func: not found par_sh_env_parallel_session /bin/sh: XXX: level2func: not found
par_sh_env_parallel_session /bin/sh: XXX: level2alias: not found par_sh_env_parallel_session /bin/sh: XXX: level2alias: not found
@ -1652,24 +1652,24 @@ par_dash_env_parallel_session /bin/dash: XXX: Bad substitution
par_dash_env_parallel_session ### level0+1+2 should be transferred par_dash_env_parallel_session ### level0+1+2 should be transferred
par_dash_env_parallel_session l0var par_dash_env_parallel_session l0var
par_dash_env_parallel_session l0alias par_dash_env_parallel_session l0alias
par_dash_env_parallel_session script: 32: level0func: not found par_dash_env_parallel_session script: 30: level0func: not found
par_dash_env_parallel_session script: 32: Bad substitution par_dash_env_parallel_session script: 30: Bad substitution
par_dash_env_parallel_session l0var par_dash_env_parallel_session l0var
par_dash_env_parallel_session l0alias par_dash_env_parallel_session l0alias
par_dash_env_parallel_session /bin/dash: XXX: level0func: not found par_dash_env_parallel_session /bin/dash: XXX: level0func: not found
par_dash_env_parallel_session /bin/dash: XXX: Bad substitution par_dash_env_parallel_session /bin/dash: XXX: Bad substitution
par_dash_env_parallel_session l1var par_dash_env_parallel_session l1var
par_dash_env_parallel_session l1alias par_dash_env_parallel_session l1alias
par_dash_env_parallel_session script: 32: level1func: not found par_dash_env_parallel_session script: 30: level1func: not found
par_dash_env_parallel_session script: 32: Bad substitution par_dash_env_parallel_session script: 30: Bad substitution
par_dash_env_parallel_session l1var par_dash_env_parallel_session l1var
par_dash_env_parallel_session l1alias par_dash_env_parallel_session l1alias
par_dash_env_parallel_session /bin/dash: XXX: level1func: not found par_dash_env_parallel_session /bin/dash: XXX: level1func: not found
par_dash_env_parallel_session /bin/dash: XXX: Bad substitution par_dash_env_parallel_session /bin/dash: XXX: Bad substitution
par_dash_env_parallel_session l2var par_dash_env_parallel_session l2var
par_dash_env_parallel_session l2alias par_dash_env_parallel_session l2alias
par_dash_env_parallel_session script: 32: level2func: not found par_dash_env_parallel_session script: 30: level2func: not found
par_dash_env_parallel_session script: 32: Bad substitution par_dash_env_parallel_session script: 30: Bad substitution
par_dash_env_parallel_session l2var par_dash_env_parallel_session l2var
par_dash_env_parallel_session l2alias par_dash_env_parallel_session l2alias
par_dash_env_parallel_session /bin/dash: XXX: level2func: not found par_dash_env_parallel_session /bin/dash: XXX: level2func: not found
@ -1815,21 +1815,21 @@ par_bash_underscore variables in aliases in and arrays in functions work
par_bash_underscore variables in aliases in and arrays in functions work par_bash_underscore variables in aliases in and arrays in functions work
par_bash_underscore variables in aliases in and arrays in functions work par_bash_underscore variables in aliases in and arrays in functions work
par_bash_underscore variables in aliases in and arrays in functions work par_bash_underscore variables in aliases in and arrays in functions work
par_bash_underscore script: line XX: not_copied_alias: command not found par_bash_underscore script: line XXX: not_copied_alias: command not found
par_bash_underscore script: line XX: not_copied_func: command not found par_bash_underscore script: line XXX: not_copied_func: command not found
par_bash_underscore error=OK par_bash_underscore error=OK
par_bash_underscore error=OK par_bash_underscore error=OK
par_bash_underscore aliases in and arrays in functions work par_bash_underscore aliases in and arrays in functions work
par_bash_underscore aliases in and arrays in functions work par_bash_underscore aliases in and arrays in functions work
par_bash_underscore aliases in functions work par_bash_underscore aliases in functions work
par_bash_underscore aliases in functions work par_bash_underscore aliases in functions work
par_bash_underscore /bin/bash: line XX: myecho: command not found par_bash_underscore environment: line XXX: myecho: command not found
par_bash_underscore OK if no myecho ^^^^^^^^^^^^^^^^^^^^^^^^^ par_bash_underscore OK if no myecho ^^^^^^^^^^^^^^^^^^^^^^^^^
par_bash_underscore script: line XX: myecho: command not found par_bash_underscore script: line XXX: myecho: command not found
par_bash_underscore OK if no myecho ^^^^^^^^^^^^^^^^^^^^^^^^^ par_bash_underscore OK if no myecho ^^^^^^^^^^^^^^^^^^^^^^^^^
par_bash_underscore /bin/bash: line XX: myfunc: command not found par_bash_underscore /bin/bash: line XXX: myfunc: command not found
par_bash_underscore OK if no myfunc ^^^^^^^^^^^^^^^^^^^^^^^^^ par_bash_underscore OK if no myfunc ^^^^^^^^^^^^^^^^^^^^^^^^^
par_bash_underscore script: line XX: myfunc: command not found par_bash_underscore script: line XXX: myfunc: command not found
par_bash_underscore OK if no myfunc ^^^^^^^^^^^^^^^^^^^^^^^^^ par_bash_underscore OK if no myfunc ^^^^^^^^^^^^^^^^^^^^^^^^^
par_bash_parset parset par_bash_parset parset
par_bash_parset ### parset into array par_bash_parset ### parset into array
@ -2293,24 +2293,24 @@ par_ash_env_parallel_session /bin/ash: XXX: Bad substitution
par_ash_env_parallel_session ### level0+1+2 should be transferred par_ash_env_parallel_session ### level0+1+2 should be transferred
par_ash_env_parallel_session l0var par_ash_env_parallel_session l0var
par_ash_env_parallel_session l0alias par_ash_env_parallel_session l0alias
par_ash_env_parallel_session script: 32: level0func: not found par_ash_env_parallel_session script: 30: level0func: not found
par_ash_env_parallel_session script: 32: Bad substitution par_ash_env_parallel_session script: 30: Bad substitution
par_ash_env_parallel_session l0var par_ash_env_parallel_session l0var
par_ash_env_parallel_session l0alias par_ash_env_parallel_session l0alias
par_ash_env_parallel_session /bin/ash: XXX: level0func: not found par_ash_env_parallel_session /bin/ash: XXX: level0func: not found
par_ash_env_parallel_session /bin/ash: XXX: Bad substitution par_ash_env_parallel_session /bin/ash: XXX: Bad substitution
par_ash_env_parallel_session l1var par_ash_env_parallel_session l1var
par_ash_env_parallel_session l1alias par_ash_env_parallel_session l1alias
par_ash_env_parallel_session script: 32: level1func: not found par_ash_env_parallel_session script: 30: level1func: not found
par_ash_env_parallel_session script: 32: Bad substitution par_ash_env_parallel_session script: 30: Bad substitution
par_ash_env_parallel_session l1var par_ash_env_parallel_session l1var
par_ash_env_parallel_session l1alias par_ash_env_parallel_session l1alias
par_ash_env_parallel_session /bin/ash: XXX: level1func: not found par_ash_env_parallel_session /bin/ash: XXX: level1func: not found
par_ash_env_parallel_session /bin/ash: XXX: Bad substitution par_ash_env_parallel_session /bin/ash: XXX: Bad substitution
par_ash_env_parallel_session l2var par_ash_env_parallel_session l2var
par_ash_env_parallel_session l2alias par_ash_env_parallel_session l2alias
par_ash_env_parallel_session script: 32: level2func: not found par_ash_env_parallel_session script: 30: level2func: not found
par_ash_env_parallel_session script: 32: Bad substitution par_ash_env_parallel_session script: 30: Bad substitution
par_ash_env_parallel_session l2var par_ash_env_parallel_session l2var
par_ash_env_parallel_session l2alias par_ash_env_parallel_session l2alias
par_ash_env_parallel_session /bin/ash: XXX: level2func: not found par_ash_env_parallel_session /bin/ash: XXX: level2func: not found

View file

@ -13,7 +13,7 @@ This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing. If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
More about funding GNU Parallel and the citation notice: More about funding GNU Parallel and the citation notice:
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice https://www.gnu.org/software/parallel/parallel_design.html#citation-notice
To silence this citation notice: run 'parallel --citation' once. To silence this citation notice: run 'parallel --citation' once.
@ -33,7 +33,7 @@ This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing. If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
More about funding GNU Parallel and the citation notice: More about funding GNU Parallel and the citation notice:
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice https://www.gnu.org/software/parallel/parallel_design.html#citation-notice
To silence this citation notice: run 'parallel --citation' once. To silence this citation notice: run 'parallel --citation' once.
@ -50,7 +50,7 @@ This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing. If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
More about funding GNU Parallel and the citation notice: More about funding GNU Parallel and the citation notice:
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice https://www.gnu.org/software/parallel/parallel_design.html#citation-notice
To silence this citation notice: run 'parallel --citation' once. To silence this citation notice: run 'parallel --citation' once.
@ -71,7 +71,7 @@ This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing. If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
More about funding GNU Parallel and the citation notice: More about funding GNU Parallel and the citation notice:
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice https://www.gnu.org/software/parallel/parallel_design.html#citation-notice
To silence this citation notice: run 'parallel --citation' once. To silence this citation notice: run 'parallel --citation' once.
@ -88,7 +88,7 @@ If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
More about funding GNU Parallel and the citation notice: More about funding GNU Parallel and the citation notice:
https://lists.gnu.org/archive/html/parallel/2013-11/msg00006.html https://lists.gnu.org/archive/html/parallel/2013-11/msg00006.html
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice https://www.gnu.org/software/parallel/parallel_design.html#citation-notice
https://git.savannah.gnu.org/cgit/parallel.git/tree/doc/citation-notice-faq.txt https://git.savannah.gnu.org/cgit/parallel.git/tree/doc/citation-notice-faq.txt
mentioned in the release notes of next version of GNU Parallel. mentioned in the release notes of next version of GNU Parallel.

View file

@ -2,13 +2,13 @@ par_big_func 1 3XXX 91XXX
par_big_func 1 3XXX 91XXX par_big_func 1 3XXX 91XXX
par_big_func 1 3XXX 91XXX par_big_func 1 3XXX 91XXX
par_big_func 1 1XXX 44XXX par_big_func 1 1XXX 44XXX
par_big_func_name 1 820 19XXX par_big_func_name 19XXX
par_big_func_name 1 820 19XXX par_big_func_name 19XXX
par_big_func_name 1 820 19XXX par_big_func_name 19XXX
par_big_func_name 1 820 19XXX par_big_func_name 19XXX
par_big_func_name 1 820 19XXX par_big_func_name 19XXX
par_big_func_name 1 820 19XXX par_big_func_name 19XXX
par_big_func_name 1 80 1XXX par_big_func_name 2XXX
par_big_var_func_name 1 816 19XXX par_big_var_func_name 1 816 19XXX
par_big_var_func_name 1 816 19XXX par_big_var_func_name 1 816 19XXX
par_big_var_func_name 1 816 19XXX par_big_var_func_name 1 816 19XXX
@ -69,32 +69,32 @@ par_many_var 1 980 23XXX
par_many_var 1 980 23XXX par_many_var 1 980 23XXX
par_many_var 1 980 23XXX par_many_var 1 980 23XXX
par_many_var 1 788 18XXX par_many_var 1 788 18XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 264 6XXX par_many_var_big_func 6XXX
par_many_var_big_func 1 68 1XXX par_many_var_big_func 4XXX
par_many_var_func 1 2XXX 59XXX par_many_var_func 1 2XXX 59XXX
par_many_var_func 1 2XXX 59XXX par_many_var_func 1 2XXX 59XXX
par_many_var_func 1 1XXX 40XXX par_many_var_func 1 1XXX 40XXX

View file

@ -499,8 +499,8 @@ echo C
sleep 1 sleep 1
echo 0 > my_jobs echo 0 > my_jobs
wait wait
parallel: Warning: Only enough file handles to run 248 jobs in parallel. parallel: Warning: Only enough file handles to run 247 jobs in parallel.
parallel: Warning: Try running 'parallel -j0 -N 248 --pipe parallel -j0' parallel: Warning: Try running 'parallel -j0 -N 247 --pipe parallel -j0'
parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`) parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
parallel: Warning: or increasing /proc/sys/fs/file-max parallel: Warning: or increasing /proc/sys/fs/file-max
@ -1271,7 +1271,7 @@ This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing. If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
More about funding GNU Parallel and the citation notice: More about funding GNU Parallel and the citation notice:
https://lists.gnu.org/archive/html/parallel/2013-11/msg00006.html https://lists.gnu.org/archive/html/parallel/2013-11/msg00006.html
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice https://www.gnu.org/software/parallel/parallel_design.html#citation-notice
https://git.savannah.gnu.org/cgit/parallel.git/tree/doc/citation-notice-faq.txt https://git.savannah.gnu.org/cgit/parallel.git/tree/doc/citation-notice-faq.txt
If you send a copy of your published article to tange@gnu.org, it will be If you send a copy of your published article to tange@gnu.org, it will be
mentioned in the release notes of next version of GNU Parallel. mentioned in the release notes of next version of GNU Parallel.