diff --git a/doc/haikus b/doc/haikus index 613425c1..3fe1e0d5 100644 --- a/doc/haikus +++ b/doc/haikus @@ -4,6 +4,9 @@ Quote of the month: + GNU Parallel alone provides more value than moreutils + -- Ferret7446@news.ycombinator.com + GNU parallel ftw -- hostux.social/@rmpr @_paulmairo@twitter diff --git a/src/env_parallel.ash b/src/env_parallel.ash index 41515f2e..24298b61 100755 --- a/src/env_parallel.ash +++ b/src/env_parallel.ash @@ -1,13 +1,19 @@ #!/usr/bin/env ash -# This file must be sourced in ash: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # -# . env_parallel.ash +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash +# source env_parallel.bash +# source env_parallel.ksh +# source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -27,12 +33,34 @@ # # SPDX-FileCopyrightText: 2021-2023 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc. # SPDX-License-Identifier: GPL-3.0-or-later -# shellcheck disable=SC2006 shell=dash +# shellcheck disable=SC2006 env_parallel() { - # based on env_parallel.sh + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT="sh" + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { # alias fails on Unixware 5 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 @@ -42,7 +70,22 @@ env_parallel() { fi done } + _names_of_ALIASES_bash() { + # No aliases will return false. This error should be ignored. + # shellcheck disable=SC3044 + compgen -a || true + } + _names_of_ALIASES_ksh() { + alias | perl -pe 's/=.*//' + } + _names_of_ALIASES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)aliases} + } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { # alias may return: # myalias='definition' (GNU/Linux ash) # alias myalias='definition' (FreeBSD ash) @@ -51,23 +94,104 @@ env_parallel() { echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" done } + _bodies_of_ALIASES_bash() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + # shellcheck disable=SC2046 + if [ $(alias "$_i" | wc -l) = 1 ] ; then + true Alias is a single line. Good. + else + _warning_PAR "Alias '$_i' contains newline." + _warning_PAR "Make sure the command has at least one newline after '$_i'." + _warning_PAR "See BUGS in 'man env_parallel'." + fi + done + alias "$@" + } + _bodies_of_ALIASES_ksh() { + alias "$@" | perl -pe 's/^/alias /; + sub warning { print STDERR "env_parallel: Warning: @_\n"; } + if(/^alias (\S+)=\$.*\\n/) { + warning("Alias \"$1\" contains newline."); + warning("Make sure the command has at least one newline after \"$1\"."); + warning("See BUGS in \"man env_parallel\"."); + }' + + } + _bodies_of_ALIASES_zsh() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + echo 'alias '"$(alias "$_i")" + done + } + _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + compgen -A function + } _names_of_maybe_FUNCTIONS() { set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' } - _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_sh() { # myfunc is a function # shellcheck disable=SC2046 LANG=C type `_names_of_maybe_FUNCTIONS` | perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' } + _names_of_FUNCTIONS_ksh() { + # shellcheck disable=SC3044 + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)functions} + } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' } + _bodies_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { + functions "$@" + } + _bodies_of_FUNCTIONS_zsh() { + # shellcheck disable=SC3044 + typeset -f "$@" + } _names_of_VARIABLES() { + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { # This may screw up if variables contain \n and = set | perl -ne 's/^(\S+?)=.*/$1/ and print;' } + _names_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + compgen -A variable + } + _names_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset +p | + perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + uniq + } + _names_of_VARIABLES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)parameters} + } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { # Crappy typeset -p for _i in "$@" do @@ -77,13 +201,44 @@ env_parallel() { echo done } + _bodies_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { # These names cannot be detected echo '(_|TIMEOUT|IFS)' } + _ignore_HARDCODED_bash() { + # Copying $RANDOM will cause it not to be random + # The rest cannot be detected as read-only + echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' + } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { + # These names cannot be detected + echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' + } _ignore_READONLY() { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { # shellcheck disable=SC1078,SC1079,SC2026 - readonly | perl -e '@r = map { + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -98,6 +253,19 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + # shellcheck disable=SC3044 + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -132,7 +300,7 @@ env_parallel() { _names_of_maybe_FUNCTIONS| _parallel_exit_CODE| _prefix_PARALLEL_ENV| - _prefix_PARALLEL_ENV| + _prefix_PARALLEL_ENV_bash| _remove_bad_NAMES| _remove_readonly| _variable_NAMES| @@ -146,6 +314,15 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } + _prefix_PARALLEL_ENV_bash() { + # shellcheck disable=SC3044 + shopt 2>/dev/null | + perl -pe 's:\s+off:;: and s/^/shopt -u /; + s:\s+on:;: and s/^/shopt -s /; + s:;$:&>/dev/null;:'; + echo 'shopt -s expand_aliases &>/dev/null'; + } + _get_ignored_VARS() { perl -e ' for(@ARGV){ @@ -309,19 +486,50 @@ env_parallel() { fi unset _variable_NAMES - # shellcheck disable=SC2006 - PARALLEL_ENV="` - $_list_alias_BODIES; - $_list_function_BODIES; - $_list_variable_VALUES; - `" + if $_eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_prefix_PARALLEL_ENV; + eval $_list_alias_BODIES; + eval $_list_function_BODIES; + eval $_list_variable_VALUES; + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV + # Free up some env space unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE - unset _remove_bad_NAMES _grep_REGEXP + unset _remove_bad_NAMES _grep_REGEXP _parse_READONLY unset _prefix_PARALLEL_ENV + unset _ignore_READONLY_sh _ignore_READONLY_bash + unset _ignore_READONLY_ksh _ignore_READONLY_zsh + unset _ignore_HARDCODED_sh _ignore_HARDCODED_bash + unset _ignore_HARDCODED_ksh _ignore_HARDCODED_zsh + unset _bodies_of_ALIASES_ksh _bodies_of_ALIASES_sh + unset _bodies_of_ALIASES_zsh _bodies_of_FUNCTIONS_bash + unset _bodies_of_FUNCTIONS_ksh _bodies_of_FUNCTIONS_sh + unset _bodies_of_FUNCTIONS_zsh _bodies_of_VARIABLES_bash + unset _bodies_of_VARIABLES_ksh _bodies_of_VARIABLES_sh + unset _bodies_of_VARIABLES_zsh + unset _names_of_ALIASES _names_of_ALIASES_bash + unset _names_of_ALIASES_ksh _names_of_ALIASES_sh + unset _names_of_ALIASES_zsh _names_of_FUNCTIONS + unset _names_of_FUNCTIONS_bash _names_of_FUNCTIONS_ksh + unset _names_of_FUNCTIONS_sh _names_of_FUNCTIONS_zsh + unset _names_of_VARIABLES _names_of_VARIABLES_bash + unset _names_of_VARIABLES_ksh _names_of_VARIABLES_sh + unset _names_of_VARIABLES_zsh _names_of_maybe_FUNCTIONS + # Test if environment is too big by running 'true' # shellcheck disable=SC2006,SC2092 if `_which_PAR true` >/dev/null 2>/dev/null ; then @@ -412,7 +620,7 @@ _parset_main() { # Bash: declare -A myassoc=( ) # Zsh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( ) - # shellcheck disable=SC2039,SC2169 + # shellcheck disable=SC2039,SC2169,SC3044 if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then # This is an associative array diff --git a/src/env_parallel.bash b/src/env_parallel.bash index 108a0114..fed62fcd 100755 --- a/src/env_parallel.bash +++ b/src/env_parallel.bash @@ -1,13 +1,19 @@ #!/usr/bin/env bash -# This file must be sourced in bash: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash # source env_parallel.bash +# source env_parallel.ksh +# source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -30,17 +36,70 @@ # shellcheck disable=SC2006 env_parallel() { - # env_parallel.bash + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT="sh" + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { + # alias fails on Unixware 5 + 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 + # or just part of a multiline alias definition + if alias "$_i" >/dev/null 2>/dev/null; then + echo "$_i" + fi + done + } + _names_of_ALIASES_bash() { # No aliases will return false. This error should be ignored. + # shellcheck disable=SC3044 compgen -a || true } + _names_of_ALIASES_ksh() { + alias | perl -pe 's/=.*//' + } + _names_of_ALIASES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)aliases} + } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { + # alias may return: + # myalias='definition' (GNU/Linux ash) + # alias myalias='definition' (FreeBSD ash) + # so remove 'alias ' from first line + for _i in "$@"; do + echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" + done + } + _bodies_of_ALIASES_bash() { + # shellcheck disable=SC3043 local _i for _i in "$@"; do # shellcheck disable=SC2046 - if [ $(alias "$_i" | wc -l) == 1 ] ; then + if [ $(alias "$_i" | wc -l) = 1 ] ; then true Alias is a single line. Good. else _warning_PAR "Alias '$_i' contains newline." @@ -50,26 +109,140 @@ env_parallel() { done alias "$@" } + _bodies_of_ALIASES_ksh() { + alias "$@" | perl -pe 's/^/alias /; + sub warning { print STDERR "env_parallel: Warning: @_\n"; } + if(/^alias (\S+)=\$.*\\n/) { + warning("Alias \"$1\" contains newline."); + warning("Make sure the command has at least one newline after \"$1\"."); + warning("See BUGS in \"man env_parallel\"."); + }' + + } + _bodies_of_ALIASES_zsh() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + echo 'alias '"$(alias "$_i")" + done + } _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 compgen -A function } + _names_of_maybe_FUNCTIONS() { + set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' + } + _names_of_FUNCTIONS_sh() { + # myfunc is a function + # shellcheck disable=SC2046 + LANG=C type `_names_of_maybe_FUNCTIONS` | + perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' + } + _names_of_FUNCTIONS_ksh() { + # shellcheck disable=SC3044 + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)functions} + } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { + LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' + } + _bodies_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { + functions "$@" + } + _bodies_of_FUNCTIONS_zsh() { + # shellcheck disable=SC3044 typeset -f "$@" } _names_of_VARIABLES() { + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { + # This may screw up if variables contain \n and = + set | perl -ne 's/^(\S+?)=.*/$1/ and print;' + } + _names_of_VARIABLES_bash() { + # shellcheck disable=SC3044 compgen -A variable } + _names_of_VARIABLES_ksh() { + # mksh: typeset +p | + # perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + # uniq + # ksh: typeset +p | perl -pe 's/^typeset .. //' + # shellcheck disable=SC3044 + typeset +p | + perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + uniq + } + _names_of_VARIABLES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)parameters} + } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { + # Crappy typeset -p + for _i in "$@" + do + perl -e 'print @ARGV' "$_i=" + 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;"; + echo + done + } + _bodies_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { + # shellcheck disable=SC3044 typeset -p "$@" } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_bash() { # Copying $RANDOM will cause it not to be random # The rest cannot be detected as read-only echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { + # These names cannot be detected + echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' + } _ignore_READONLY() { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { # shellcheck disable=SC1078,SC1079,SC2026 - readonly | perl -e '@r = map { + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -84,6 +257,19 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + # shellcheck disable=SC3044 + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -118,7 +304,7 @@ env_parallel() { _names_of_maybe_FUNCTIONS| _parallel_exit_CODE| _prefix_PARALLEL_ENV| - _prefix_PARALLEL_ENV| + _prefix_PARALLEL_ENV_bash| _remove_bad_NAMES| _remove_readonly| _variable_NAMES| @@ -132,7 +318,8 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } - _prefix_PARALLEL_ENV() { + _prefix_PARALLEL_ENV_bash() { + # shellcheck disable=SC3044 shopt 2>/dev/null | perl -pe 's:\s+off:;: and s/^/shopt -u /; s:\s+on:;: and s/^/shopt -s /; @@ -207,9 +394,9 @@ env_parallel() { echo "env_parallel: Error: $*" >&2 } - # Bash is broken in version 3.2.25 and 4.2.39 - # The crazy '[ "`...`" == "" ]' is needed for the same reason - if [ "`_which_PAR parallel`" == "" ]; then + if _which_PAR parallel >/dev/null; then + true parallel found in path + else # shellcheck disable=SC2016 _error_PAR 'parallel must be in $PATH.' return 255 @@ -226,9 +413,7 @@ env_parallel() { unset _get_ignored_VARS # --record-env - # Bash is broken in version 3.2.25 and 4.2.39 - # The crazy '[ "`...`" == 0 ]' is needed for the same reason - if [ "`perl -e 'exit grep { /^--record-env$/ } @ARGV' -- "$@"; echo $?`" == 0 ] ; then + if perl -e 'exit grep { /^--record-env$/ } @ARGV' -- "$@"; then true skip else (_names_of_ALIASES; @@ -239,9 +424,7 @@ env_parallel() { fi # --session - # Bash is broken in version 3.2.25 and 4.2.39 - # The crazy '[ "`...`" == 0 ]' is needed for the same reason - if [ "`perl -e 'exit grep { /^--session$/ } @ARGV' -- "$@"; echo $?`" == 0 ] ; then + if perl -e 'exit grep { /^--session$/ } @ARGV' -- "$@"; then true skip else # Insert ::: between each level of session @@ -266,9 +449,7 @@ env_parallel() { export PARALLEL_IGNORED_NAMES return 0 fi - # Bash is broken in version 3.2.25 and 4.2.39 - # The crazy '[ "`...`" == 0 ]' is needed for the same reason - if [ "`perl -e 'exit grep { /^--end.?session$/ } @ARGV' -- "$@"; echo $?`" == 0 ] ; then + if perl -e 'exit grep { /^--end.?session$/ } @ARGV' -- "$@"; then true skip else # Pop off last ::: from PARALLEL_IGNORED_NAMES @@ -309,24 +490,53 @@ env_parallel() { fi unset _variable_NAMES - _which_TRUE="`_which_PAR true`" - # Copy shopt (so e.g. extended globbing works) - # But force expand_aliases as aliases otherwise do not work - PARALLEL_ENV="` - _prefix_PARALLEL_ENV - $_list_alias_BODIES; - $_list_function_BODIES; - $_list_variable_VALUES; - `" + if $_eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_prefix_PARALLEL_ENV; + eval $_list_alias_BODIES; + eval $_list_function_BODIES; + eval $_list_variable_VALUES; + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV + # Free up some env space unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE - unset _remove_bad_NAMES _grep_REGEXP + unset _remove_bad_NAMES _grep_REGEXP _parse_READONLY unset _prefix_PARALLEL_ENV - # Test if environment is too big - if [ "`_which_PAR true`" == "$_which_TRUE" ] ; then + unset _ignore_READONLY_sh _ignore_READONLY_bash + unset _ignore_READONLY_ksh _ignore_READONLY_zsh + unset _ignore_HARDCODED_sh _ignore_HARDCODED_bash + unset _ignore_HARDCODED_ksh _ignore_HARDCODED_zsh + unset _bodies_of_ALIASES_ksh _bodies_of_ALIASES_sh + unset _bodies_of_ALIASES_zsh _bodies_of_FUNCTIONS_bash + unset _bodies_of_FUNCTIONS_ksh _bodies_of_FUNCTIONS_sh + unset _bodies_of_FUNCTIONS_zsh _bodies_of_VARIABLES_bash + unset _bodies_of_VARIABLES_ksh _bodies_of_VARIABLES_sh + unset _bodies_of_VARIABLES_zsh + unset _names_of_ALIASES _names_of_ALIASES_bash + unset _names_of_ALIASES_ksh _names_of_ALIASES_sh + unset _names_of_ALIASES_zsh _names_of_FUNCTIONS + unset _names_of_FUNCTIONS_bash _names_of_FUNCTIONS_ksh + unset _names_of_FUNCTIONS_sh _names_of_FUNCTIONS_zsh + unset _names_of_VARIABLES _names_of_VARIABLES_bash + unset _names_of_VARIABLES_ksh _names_of_VARIABLES_sh + unset _names_of_VARIABLES_zsh _names_of_maybe_FUNCTIONS + + # Test if environment is too big by running 'true' + # shellcheck disable=SC2006,SC2092 + if `_which_PAR true` >/dev/null 2>/dev/null ; then parallel "$@" _parallel_exit_CODE=$? # Clean up variables/functions @@ -414,7 +624,7 @@ _parset_main() { # Bash: declare -A myassoc=( ) # Zsh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( ) - # shellcheck disable=SC2039,SC2169 + # shellcheck disable=SC2039,SC2169,SC3044 if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then # This is an associative array diff --git a/src/env_parallel.dash b/src/env_parallel.dash index 0be830c4..7a7a259f 100755 --- a/src/env_parallel.dash +++ b/src/env_parallel.dash @@ -1,13 +1,19 @@ #!/usr/bin/env dash -# This file must be sourced in dash: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # -# . env_parallel.dash +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash +# source env_parallel.bash +# source env_parallel.ksh +# source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -30,9 +36,31 @@ # shellcheck disable=SC2006 env_parallel() { - # based on env_parallel.sh + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT="sh" + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { # alias fails on Unixware 5 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 @@ -42,7 +70,22 @@ env_parallel() { fi done } + _names_of_ALIASES_bash() { + # No aliases will return false. This error should be ignored. + # shellcheck disable=SC3044 + compgen -a || true + } + _names_of_ALIASES_ksh() { + alias | perl -pe 's/=.*//' + } + _names_of_ALIASES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)aliases} + } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { # alias may return: # myalias='definition' (GNU/Linux ash) # alias myalias='definition' (FreeBSD ash) @@ -51,23 +94,104 @@ env_parallel() { echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" done } + _bodies_of_ALIASES_bash() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + # shellcheck disable=SC2046 + if [ $(alias "$_i" | wc -l) = 1 ] ; then + true Alias is a single line. Good. + else + _warning_PAR "Alias '$_i' contains newline." + _warning_PAR "Make sure the command has at least one newline after '$_i'." + _warning_PAR "See BUGS in 'man env_parallel'." + fi + done + alias "$@" + } + _bodies_of_ALIASES_ksh() { + alias "$@" | perl -pe 's/^/alias /; + sub warning { print STDERR "env_parallel: Warning: @_\n"; } + if(/^alias (\S+)=\$.*\\n/) { + warning("Alias \"$1\" contains newline."); + warning("Make sure the command has at least one newline after \"$1\"."); + warning("See BUGS in \"man env_parallel\"."); + }' + + } + _bodies_of_ALIASES_zsh() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + echo 'alias '"$(alias "$_i")" + done + } + _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + compgen -A function + } _names_of_maybe_FUNCTIONS() { set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' } - _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_sh() { # myfunc is a function # shellcheck disable=SC2046 LANG=C type `_names_of_maybe_FUNCTIONS` | perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' } + _names_of_FUNCTIONS_ksh() { + # shellcheck disable=SC3044 + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)functions} + } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' } + _bodies_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { + functions "$@" + } + _bodies_of_FUNCTIONS_zsh() { + # shellcheck disable=SC3044 + typeset -f "$@" + } _names_of_VARIABLES() { + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { # This may screw up if variables contain \n and = set | perl -ne 's/^(\S+?)=.*/$1/ and print;' } + _names_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + compgen -A variable + } + _names_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset +p | + perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + uniq + } + _names_of_VARIABLES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)parameters} + } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { # Crappy typeset -p for _i in "$@" do @@ -77,13 +201,44 @@ env_parallel() { echo done } + _bodies_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { # These names cannot be detected echo '(_|TIMEOUT|IFS)' } + _ignore_HARDCODED_bash() { + # Copying $RANDOM will cause it not to be random + # The rest cannot be detected as read-only + echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' + } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { + # These names cannot be detected + echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' + } _ignore_READONLY() { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { # shellcheck disable=SC1078,SC1079,SC2026 - readonly | perl -e '@r = map { + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -98,6 +253,19 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + # shellcheck disable=SC3044 + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -132,7 +300,7 @@ env_parallel() { _names_of_maybe_FUNCTIONS| _parallel_exit_CODE| _prefix_PARALLEL_ENV| - _prefix_PARALLEL_ENV| + _prefix_PARALLEL_ENV_bash| _remove_bad_NAMES| _remove_readonly| _variable_NAMES| @@ -146,6 +314,15 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } + _prefix_PARALLEL_ENV_bash() { + # shellcheck disable=SC3044 + shopt 2>/dev/null | + perl -pe 's:\s+off:;: and s/^/shopt -u /; + s:\s+on:;: and s/^/shopt -s /; + s:;$:&>/dev/null;:'; + echo 'shopt -s expand_aliases &>/dev/null'; + } + _get_ignored_VARS() { perl -e ' for(@ARGV){ @@ -309,19 +486,50 @@ env_parallel() { fi unset _variable_NAMES - # shellcheck disable=SC2006 - PARALLEL_ENV="` - $_list_alias_BODIES; - $_list_function_BODIES; - $_list_variable_VALUES; - `" + if $_eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_prefix_PARALLEL_ENV; + eval $_list_alias_BODIES; + eval $_list_function_BODIES; + eval $_list_variable_VALUES; + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV + # Free up some env space unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE - unset _remove_bad_NAMES _grep_REGEXP + unset _remove_bad_NAMES _grep_REGEXP _parse_READONLY unset _prefix_PARALLEL_ENV + unset _ignore_READONLY_sh _ignore_READONLY_bash + unset _ignore_READONLY_ksh _ignore_READONLY_zsh + unset _ignore_HARDCODED_sh _ignore_HARDCODED_bash + unset _ignore_HARDCODED_ksh _ignore_HARDCODED_zsh + unset _bodies_of_ALIASES_ksh _bodies_of_ALIASES_sh + unset _bodies_of_ALIASES_zsh _bodies_of_FUNCTIONS_bash + unset _bodies_of_FUNCTIONS_ksh _bodies_of_FUNCTIONS_sh + unset _bodies_of_FUNCTIONS_zsh _bodies_of_VARIABLES_bash + unset _bodies_of_VARIABLES_ksh _bodies_of_VARIABLES_sh + unset _bodies_of_VARIABLES_zsh + unset _names_of_ALIASES _names_of_ALIASES_bash + unset _names_of_ALIASES_ksh _names_of_ALIASES_sh + unset _names_of_ALIASES_zsh _names_of_FUNCTIONS + unset _names_of_FUNCTIONS_bash _names_of_FUNCTIONS_ksh + unset _names_of_FUNCTIONS_sh _names_of_FUNCTIONS_zsh + unset _names_of_VARIABLES _names_of_VARIABLES_bash + unset _names_of_VARIABLES_ksh _names_of_VARIABLES_sh + unset _names_of_VARIABLES_zsh _names_of_maybe_FUNCTIONS + # Test if environment is too big by running 'true' # shellcheck disable=SC2006,SC2092 if `_which_PAR true` >/dev/null 2>/dev/null ; then @@ -412,7 +620,7 @@ _parset_main() { # Bash: declare -A myassoc=( ) # Zsh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( ) - # shellcheck disable=SC2039,SC2169 + # shellcheck disable=SC2039,SC2169,SC3044 if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then # This is an associative array diff --git a/src/env_parallel.ksh b/src/env_parallel.ksh index 9c26405d..b4a8f898 100755 --- a/src/env_parallel.ksh +++ b/src/env_parallel.ksh @@ -1,13 +1,19 @@ #!/usr/bin/env ksh -# This file must be sourced in ksh: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash +# source env_parallel.bash # source env_parallel.ksh +# source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -30,12 +36,80 @@ # shellcheck disable=SC2006 env_parallel() { - # env_parallel.ksh + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT="sh" + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { + # alias fails on Unixware 5 + 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 + # or just part of a multiline alias definition + if alias "$_i" >/dev/null 2>/dev/null; then + echo "$_i" + fi + done + } + _names_of_ALIASES_bash() { + # No aliases will return false. This error should be ignored. + # shellcheck disable=SC3044 + compgen -a || true + } + _names_of_ALIASES_ksh() { alias | perl -pe 's/=.*//' } + _names_of_ALIASES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)aliases} + } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { + # alias may return: + # myalias='definition' (GNU/Linux ash) + # alias myalias='definition' (FreeBSD ash) + # so remove 'alias ' from first line + for _i in "$@"; do + echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" + done + } + _bodies_of_ALIASES_bash() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + # shellcheck disable=SC2046 + if [ $(alias "$_i" | wc -l) = 1 ] ; then + true Alias is a single line. Good. + else + _warning_PAR "Alias '$_i' contains newline." + _warning_PAR "Make sure the command has at least one newline after '$_i'." + _warning_PAR "See BUGS in 'man env_parallel'." + fi + done + alias "$@" + } + _bodies_of_ALIASES_ksh() { alias "$@" | perl -pe 's/^/alias /; sub warning { print STDERR "env_parallel: Warning: @_\n"; } if(/^alias (\S+)=\$.*\\n/) { @@ -45,28 +119,126 @@ env_parallel() { }' } - _names_of_maybe_FUNCTIONS() { - true not used + _bodies_of_ALIASES_zsh() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + echo 'alias '"$(alias "$_i")" + done } _names_of_FUNCTIONS() { - typeset +p -f | perl -pe 's/\(\).*//' + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + compgen -A function + } + _names_of_maybe_FUNCTIONS() { + set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' + } + _names_of_FUNCTIONS_sh() { + # myfunc is a function + # shellcheck disable=SC2046 + LANG=C type `_names_of_maybe_FUNCTIONS` | + perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' + } + _names_of_FUNCTIONS_ksh() { + # shellcheck disable=SC3044 + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)functions} } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { + LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' + } + _bodies_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { functions "$@" } + _bodies_of_FUNCTIONS_zsh() { + # shellcheck disable=SC3044 + typeset -f "$@" + } _names_of_VARIABLES() { - typeset +p | perl -pe 's/^typeset .. //' + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { + # This may screw up if variables contain \n and = + set | perl -ne 's/^(\S+?)=.*/$1/ and print;' + } + _names_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + compgen -A variable + } + _names_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset +p | + perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + uniq + } + _names_of_VARIABLES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)parameters} } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { + # Crappy typeset -p + for _i in "$@" + do + perl -e 'print @ARGV' "$_i=" + 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;"; + echo + done + } + _bodies_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { + # shellcheck disable=SC3044 typeset -p "$@" } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { # These names cannot be detected echo '(_|TIMEOUT|IFS)' } + _ignore_HARDCODED_bash() { + # Copying $RANDOM will cause it not to be random + # The rest cannot be detected as read-only + echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' + } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { + # These names cannot be detected + echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' + } _ignore_READONLY() { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { # shellcheck disable=SC1078,SC1079,SC2026 - readonly | perl -e '@r = map { + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -81,6 +253,19 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + # shellcheck disable=SC3044 + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -115,7 +300,7 @@ env_parallel() { _names_of_maybe_FUNCTIONS| _parallel_exit_CODE| _prefix_PARALLEL_ENV| - _prefix_PARALLEL_ENV| + _prefix_PARALLEL_ENV_bash| _remove_bad_NAMES| _remove_readonly| _variable_NAMES| @@ -129,6 +314,15 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } + _prefix_PARALLEL_ENV_bash() { + # shellcheck disable=SC3044 + shopt 2>/dev/null | + perl -pe 's:\s+off:;: and s/^/shopt -u /; + s:\s+on:;: and s/^/shopt -s /; + s:;$:&>/dev/null;:'; + echo 'shopt -s expand_aliases &>/dev/null'; + } + _get_ignored_VARS() { perl -e ' for(@ARGV){ @@ -292,19 +486,50 @@ env_parallel() { fi unset _variable_NAMES - # shellcheck disable=SC2006 - PARALLEL_ENV="` - $_list_alias_BODIES; - $_list_function_BODIES; - $_list_variable_VALUES; - `" + if $_eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_prefix_PARALLEL_ENV; + eval $_list_alias_BODIES; + eval $_list_function_BODIES; + eval $_list_variable_VALUES; + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV + # Free up some env space unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE - unset _remove_bad_NAMES _grep_REGEXP + unset _remove_bad_NAMES _grep_REGEXP _parse_READONLY unset _prefix_PARALLEL_ENV + unset _ignore_READONLY_sh _ignore_READONLY_bash + unset _ignore_READONLY_ksh _ignore_READONLY_zsh + unset _ignore_HARDCODED_sh _ignore_HARDCODED_bash + unset _ignore_HARDCODED_ksh _ignore_HARDCODED_zsh + unset _bodies_of_ALIASES_ksh _bodies_of_ALIASES_sh + unset _bodies_of_ALIASES_zsh _bodies_of_FUNCTIONS_bash + unset _bodies_of_FUNCTIONS_ksh _bodies_of_FUNCTIONS_sh + unset _bodies_of_FUNCTIONS_zsh _bodies_of_VARIABLES_bash + unset _bodies_of_VARIABLES_ksh _bodies_of_VARIABLES_sh + unset _bodies_of_VARIABLES_zsh + unset _names_of_ALIASES _names_of_ALIASES_bash + unset _names_of_ALIASES_ksh _names_of_ALIASES_sh + unset _names_of_ALIASES_zsh _names_of_FUNCTIONS + unset _names_of_FUNCTIONS_bash _names_of_FUNCTIONS_ksh + unset _names_of_FUNCTIONS_sh _names_of_FUNCTIONS_zsh + unset _names_of_VARIABLES _names_of_VARIABLES_bash + unset _names_of_VARIABLES_ksh _names_of_VARIABLES_sh + unset _names_of_VARIABLES_zsh _names_of_maybe_FUNCTIONS + # Test if environment is too big by running 'true' # shellcheck disable=SC2006,SC2092 if `_which_PAR true` >/dev/null 2>/dev/null ; then @@ -395,7 +620,7 @@ _parset_main() { # Bash: declare -A myassoc=( ) # Zsh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( ) - # shellcheck disable=SC2039,SC2169 + # shellcheck disable=SC2039,SC2169,SC3044 if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then # This is an associative array diff --git a/src/env_parallel.mksh b/src/env_parallel.mksh index 58fcea70..23e16d37 100644 --- a/src/env_parallel.mksh +++ b/src/env_parallel.mksh @@ -1,13 +1,19 @@ #!/usr/bin/env ksh -# This file must be sourced in mksh: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash +# source env_parallel.bash +# source env_parallel.ksh # source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -30,12 +36,77 @@ # shellcheck disable=SC2006 env_parallel() { - # env_parallel.mksh + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT=sh + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { + # alias fails on Unixware 5 + 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 + # or just part of a multiline alias definition + if alias "$_i" >/dev/null 2>/dev/null; then + echo "$_i" + fi + done + } + _names_of_ALIASES_bash() { + # No aliases will return false. This error should be ignored. + compgen -a || true + } + _names_of_ALIASES_ksh() { alias | perl -pe 's/=.*//' } + _names_of_ALIASES_zsh() { + print -l ${(k)aliases} + } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { + # alias may return: + # myalias='definition' (GNU/Linux ash) + # alias myalias='definition' (FreeBSD ash) + # so remove 'alias ' from first line + for _i in "$@"; do + echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" + done + } + _bodies_of_ALIASES_bash() { + local _i + for _i in "$@"; do + # shellcheck disable=SC2046 + if [ $(alias "$_i" | wc -l) == 1 ] ; then + true Alias is a single line. Good. + else + _warning_PAR "Alias '$_i' contains newline." + _warning_PAR "Make sure the command has at least one newline after '$_i'." + _warning_PAR "See BUGS in 'man env_parallel'." + fi + done + alias "$@" + } + _bodies_of_ALIASES_ksh() { alias "$@" | perl -pe 's/^/alias /; sub warning { print STDERR "env_parallel: Warning: @_\n"; } if(/^alias (\S+)=\$.*\\n/) { @@ -45,30 +116,120 @@ env_parallel() { }' } - _names_of_maybe_FUNCTIONS() { - true not used + _bodies_of_ALIASES_zsh() { + local _i + for _i in "$@"; do + echo 'alias '"$(alias $_i)" + done } _names_of_FUNCTIONS() { - typeset +f + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + compgen -A function + } + _names_of_maybe_FUNCTIONS() { + set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' + } + _names_of_FUNCTIONS_sh() { + # myfunc is a function + # shellcheck disable=SC2046 + LANG=C type `_names_of_maybe_FUNCTIONS` | + perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' + } + _names_of_FUNCTIONS_ksh() { + # mksh = typeset +f + # ksh = typeset +p -f | perl -pe 's/\(\).*//' + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + print -l ${(k)functions} } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { + LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' + } + _bodies_of_FUNCTIONS_bash() { + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { + functions "$@" + } + _bodies_of_FUNCTIONS_zsh() { typeset -f "$@" } _names_of_VARIABLES() { + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { + # This may screw up if variables contain \n and = + set | perl -ne 's/^(\S+?)=.*/$1/ and print;' + } + _names_of_VARIABLES_bash() { + compgen -A variable + } + _names_of_VARIABLES_ksh() { + # mksh: typeset +p | + # perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + # uniq + # ksh: typeset +p | perl -pe 's/^typeset .. //' typeset +p | perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | uniq } + _names_of_VARIABLES_zsh() { + print -l ${(k)parameters} + } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { + # Crappy typeset -p + for _i in "$@" + do + perl -e 'print @ARGV' "$_i=" + 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;"; + echo + done + } + _bodies_of_VARIABLES_bash() { + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { typeset -p "$@" } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { # These names cannot be detected - echo '(_)' + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_bash() { + # Copying $RANDOM will cause it not to be random + # The rest cannot be detected as read-only + echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' + } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { + # These names cannot be detected + echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' } _ignore_READONLY() { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { # shellcheck disable=SC1078,SC1079,SC2026 - readonly | perl -e '@r = map { + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -83,6 +244,18 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -131,6 +304,14 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } + _prefix_PARALLEL_ENV_bash() { + shopt 2>/dev/null | + perl -pe 's:\s+off:;: and s/^/shopt -u /; + s:\s+on:;: and s/^/shopt -s /; + s:;$:&>/dev/null;:'; + echo 'shopt -s expand_aliases &>/dev/null'; + } + _get_ignored_VARS() { perl -e ' for(@ARGV){ @@ -294,13 +475,24 @@ env_parallel() { fi unset _variable_NAMES - # shellcheck disable=SC2006 - PARALLEL_ENV="` - $_list_alias_BODIES; - $_list_function_BODIES; - $_list_variable_VALUES; - `" + if $eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_list_alias_BODIES; + eval $_list_function_BODIES; + eval $_list_variable_VALUES; + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV + # Free up some env space unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS diff --git a/src/env_parallel.sh b/src/env_parallel.sh index b42cb917..26ec0d80 100755 --- a/src/env_parallel.sh +++ b/src/env_parallel.sh @@ -1,13 +1,19 @@ #!/usr/bin/env sh -# This file must be sourced in sh: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # -# . `which env_parallel.sh` +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash +# source env_parallel.bash +# source env_parallel.ksh +# source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -30,9 +36,31 @@ # shellcheck disable=SC2006 env_parallel() { - # env_parallel.sh + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT="sh" + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { # alias fails on Unixware 5 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 @@ -42,7 +70,22 @@ env_parallel() { fi done } + _names_of_ALIASES_bash() { + # No aliases will return false. This error should be ignored. + # shellcheck disable=SC3044 + compgen -a || true + } + _names_of_ALIASES_ksh() { + alias | perl -pe 's/=.*//' + } + _names_of_ALIASES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)aliases} + } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { # alias may return: # myalias='definition' (GNU/Linux ash) # alias myalias='definition' (FreeBSD ash) @@ -51,23 +94,104 @@ env_parallel() { echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" done } + _bodies_of_ALIASES_bash() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + # shellcheck disable=SC2046 + if [ $(alias "$_i" | wc -l) = 1 ] ; then + true Alias is a single line. Good. + else + _warning_PAR "Alias '$_i' contains newline." + _warning_PAR "Make sure the command has at least one newline after '$_i'." + _warning_PAR "See BUGS in 'man env_parallel'." + fi + done + alias "$@" + } + _bodies_of_ALIASES_ksh() { + alias "$@" | perl -pe 's/^/alias /; + sub warning { print STDERR "env_parallel: Warning: @_\n"; } + if(/^alias (\S+)=\$.*\\n/) { + warning("Alias \"$1\" contains newline."); + warning("Make sure the command has at least one newline after \"$1\"."); + warning("See BUGS in \"man env_parallel\"."); + }' + + } + _bodies_of_ALIASES_zsh() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + echo 'alias '"$(alias "$_i")" + done + } + _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + compgen -A function + } _names_of_maybe_FUNCTIONS() { set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' } - _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_sh() { # myfunc is a function # shellcheck disable=SC2046 LANG=C type `_names_of_maybe_FUNCTIONS` | perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' } + _names_of_FUNCTIONS_ksh() { + # shellcheck disable=SC3044 + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)functions} + } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' } + _bodies_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { + functions "$@" + } + _bodies_of_FUNCTIONS_zsh() { + # shellcheck disable=SC3044 + typeset -f "$@" + } _names_of_VARIABLES() { + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { # This may screw up if variables contain \n and = set | perl -ne 's/^(\S+?)=.*/$1/ and print;' } + _names_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + compgen -A variable + } + _names_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset +p | + perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + uniq + } + _names_of_VARIABLES_zsh() { + # shellcheck disable=SC2086,SC2296 + print -l ${(k)parameters} + } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { # Crappy typeset -p for _i in "$@" do @@ -77,13 +201,44 @@ env_parallel() { echo done } + _bodies_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { # These names cannot be detected echo '(_|TIMEOUT|IFS)' } + _ignore_HARDCODED_bash() { + # Copying $RANDOM will cause it not to be random + # The rest cannot be detected as read-only + echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' + } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { + # These names cannot be detected + echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' + } _ignore_READONLY() { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { # shellcheck disable=SC1078,SC1079,SC2026 - readonly | perl -e '@r = map { + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -98,6 +253,19 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + # shellcheck disable=SC3044 + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -132,7 +300,7 @@ env_parallel() { _names_of_maybe_FUNCTIONS| _parallel_exit_CODE| _prefix_PARALLEL_ENV| - _prefix_PARALLEL_ENV| + _prefix_PARALLEL_ENV_bash| _remove_bad_NAMES| _remove_readonly| _variable_NAMES| @@ -146,6 +314,15 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } + _prefix_PARALLEL_ENV_bash() { + # shellcheck disable=SC3044 + shopt 2>/dev/null | + perl -pe 's:\s+off:;: and s/^/shopt -u /; + s:\s+on:;: and s/^/shopt -s /; + s:;$:&>/dev/null;:'; + echo 'shopt -s expand_aliases &>/dev/null'; + } + _get_ignored_VARS() { perl -e ' for(@ARGV){ @@ -309,19 +486,50 @@ env_parallel() { fi unset _variable_NAMES - # shellcheck disable=SC2006 - PARALLEL_ENV="` - $_list_alias_BODIES; - $_list_function_BODIES; - $_list_variable_VALUES; - `" + if $_eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_prefix_PARALLEL_ENV; + eval $_list_alias_BODIES; + eval $_list_function_BODIES; + eval $_list_variable_VALUES; + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV + # Free up some env space unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE - unset _remove_bad_NAMES _grep_REGEXP + unset _remove_bad_NAMES _grep_REGEXP _parse_READONLY unset _prefix_PARALLEL_ENV + unset _ignore_READONLY_sh _ignore_READONLY_bash + unset _ignore_READONLY_ksh _ignore_READONLY_zsh + unset _ignore_HARDCODED_sh _ignore_HARDCODED_bash + unset _ignore_HARDCODED_ksh _ignore_HARDCODED_zsh + unset _bodies_of_ALIASES_ksh _bodies_of_ALIASES_sh + unset _bodies_of_ALIASES_zsh _bodies_of_FUNCTIONS_bash + unset _bodies_of_FUNCTIONS_ksh _bodies_of_FUNCTIONS_sh + unset _bodies_of_FUNCTIONS_zsh _bodies_of_VARIABLES_bash + unset _bodies_of_VARIABLES_ksh _bodies_of_VARIABLES_sh + unset _bodies_of_VARIABLES_zsh + unset _names_of_ALIASES _names_of_ALIASES_bash + unset _names_of_ALIASES_ksh _names_of_ALIASES_sh + unset _names_of_ALIASES_zsh _names_of_FUNCTIONS + unset _names_of_FUNCTIONS_bash _names_of_FUNCTIONS_ksh + unset _names_of_FUNCTIONS_sh _names_of_FUNCTIONS_zsh + unset _names_of_VARIABLES _names_of_VARIABLES_bash + unset _names_of_VARIABLES_ksh _names_of_VARIABLES_sh + unset _names_of_VARIABLES_zsh _names_of_maybe_FUNCTIONS + # Test if environment is too big by running 'true' # shellcheck disable=SC2006,SC2092 if `_which_PAR true` >/dev/null 2>/dev/null ; then @@ -412,7 +620,7 @@ _parset_main() { # Bash: declare -A myassoc=( ) # Zsh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( ) - # shellcheck disable=SC2039,SC2169 + # shellcheck disable=SC2039,SC2169,SC3044 if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then # This is an associative array diff --git a/src/env_parallel.zsh b/src/env_parallel.zsh index 75ba8542..44c6e39c 100755 --- a/src/env_parallel.zsh +++ b/src/env_parallel.zsh @@ -1,13 +1,19 @@ #!/usr/bin/env zsh -# This file must be sourced in zsh: +# This file must be sourced in sh/ash/dash/bash/ksh/mksh/zsh: # -# source =env_parallel.zsh +# . env_parallel.sh +# source env_parallel.ash +# source env_parallel.dash +# source env_parallel.bash +# source env_parallel.ksh +# source env_parallel.mksh +# source env_parallel.zsh # # after which 'env_parallel' works # # -# Copyright (C) 2016-2023 Ole Tange, http://ole.tange.dk and Free +# Copyright (C) 2016-2024 Ole Tange, http://ole.tange.dk and Free # Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -30,35 +36,209 @@ # shellcheck disable=SC2006 env_parallel() { - # env_parallel.zsh + # env_parallel.{sh,ash,dash,bash,ksh,mksh,zsh} + # Check shell dialect + if [ -n "$BASH_VERSION" ]; then + _shell_DIALECT=bash + _eval_needed=false + _prefix_PARALLEL_ENV=_prefix_PARALLEL_ENV_bash + elif [ -n "$ZSH_VERSION" ]; then + _shell_DIALECT=zsh + _eval_needed=true + _prefix_PARALLEL_ENV=false + elif [ -n "$KSH_VERSION" ]; then + _shell_DIALECT=ksh + _eval_needed=false + _prefix_PARALLEL_ENV=false + else + # Dash/ash - can these be detected better? + _shell_DIALECT="sh" + _eval_needed=false + _prefix_PARALLEL_ENV=false + fi _names_of_ALIASES() { + _names_of_ALIASES_$_shell_DIALECT + } + _names_of_ALIASES_sh() { + # alias fails on Unixware 5 + 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 + # or just part of a multiline alias definition + if alias "$_i" >/dev/null 2>/dev/null; then + echo "$_i" + fi + done + } + _names_of_ALIASES_bash() { + # No aliases will return false. This error should be ignored. + # shellcheck disable=SC3044 + compgen -a || true + } + _names_of_ALIASES_ksh() { + alias | perl -pe 's/=.*//' + } + _names_of_ALIASES_zsh() { + # shellcheck disable=SC2086,SC2296 print -l ${(k)aliases} } _bodies_of_ALIASES() { + _bodies_of_ALIASES_$_shell_DIALECT "$@" + } + _bodies_of_ALIASES_sh() { + # alias may return: + # myalias='definition' (GNU/Linux ash) + # alias myalias='definition' (FreeBSD ash) + # so remove 'alias ' from first line + for _i in "$@"; do + echo 'alias '"`alias "$_i" | perl -pe '1..1 and s/^alias //'`" + done + } + _bodies_of_ALIASES_bash() { + # shellcheck disable=SC3043 local _i - for _i ($@); do - echo 'alias '"$(alias $_i)" + for _i in "$@"; do + # shellcheck disable=SC2046 + if [ $(alias "$_i" | wc -l) = 1 ] ; then + true Alias is a single line. Good. + else + _warning_PAR "Alias '$_i' contains newline." + _warning_PAR "Make sure the command has at least one newline after '$_i'." + _warning_PAR "See BUGS in 'man env_parallel'." + fi + done + alias "$@" + } + _bodies_of_ALIASES_ksh() { + alias "$@" | perl -pe 's/^/alias /; + sub warning { print STDERR "env_parallel: Warning: @_\n"; } + if(/^alias (\S+)=\$.*\\n/) { + warning("Alias \"$1\" contains newline."); + warning("Make sure the command has at least one newline after \"$1\"."); + warning("See BUGS in \"man env_parallel\"."); + }' + + } + _bodies_of_ALIASES_zsh() { + # shellcheck disable=SC3043 + local _i + for _i in "$@"; do + echo 'alias '"$(alias "$_i")" done } _names_of_FUNCTIONS() { + _names_of_FUNCTIONS_$_shell_DIALECT + } + _names_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + compgen -A function + } + _names_of_maybe_FUNCTIONS() { + set | perl -ne '/^([A-Z_0-9]+)\s*\(\)\s*\{?$/i and print "$1\n"' + } + _names_of_FUNCTIONS_sh() { + # myfunc is a function + # shellcheck disable=SC2046 + LANG=C type `_names_of_maybe_FUNCTIONS` | + perl -ne '/^(\S+) is a function$/ and not $seen{$1}++ and print "$1\n"' + } + _names_of_FUNCTIONS_ksh() { + # shellcheck disable=SC3044 + typeset +f | perl -pe 's/\(\).*//; s/ .*//;' + } + _names_of_FUNCTIONS_zsh() { + # shellcheck disable=SC2086,SC2296 print -l ${(k)functions} } _bodies_of_FUNCTIONS() { + _bodies_of_FUNCTIONS_$_shell_DIALECT "$@" + } + _bodies_of_FUNCTIONS_sh() { + LANG=C type "$@" | perl -ne '/^(\S+) is a function$/ or print' + } + _bodies_of_FUNCTIONS_bash() { + # shellcheck disable=SC3044 + typeset -f "$@" + } + _bodies_of_FUNCTIONS_ksh() { + functions "$@" + } + _bodies_of_FUNCTIONS_zsh() { + # shellcheck disable=SC3044 typeset -f "$@" } _names_of_VARIABLES() { + _names_of_VARIABLES_$_shell_DIALECT + } + _names_of_VARIABLES_sh() { + # This may screw up if variables contain \n and = + set | perl -ne 's/^(\S+?)=.*/$1/ and print;' + } + _names_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + compgen -A variable + } + _names_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset +p | + perl -pe 's/^(type)?set( [-+][a-zA-Z0-9]*)* //; s/(\[\d+\])?=.*//' | + uniq + } + _names_of_VARIABLES_zsh() { + # shellcheck disable=SC2086,SC2296 print -l ${(k)parameters} } _bodies_of_VARIABLES() { + _bodies_of_VARIABLES_$_shell_DIALECT "$@" + } + _bodies_of_VARIABLES_sh() { + # Crappy typeset -p + for _i in "$@" + do + perl -e 'print @ARGV' "$_i=" + 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;"; + echo + done + } + _bodies_of_VARIABLES_bash() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_ksh() { + # shellcheck disable=SC3044 + typeset -p "$@" + } + _bodies_of_VARIABLES_zsh() { + # shellcheck disable=SC3044 typeset -p "$@" } _ignore_HARDCODED() { + _ignore_HARDCODED_$_shell_DIALECT + } + _ignore_HARDCODED_sh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_bash() { + # Copying $RANDOM will cause it not to be random + # The rest cannot be detected as read-only + echo '(RANDOM|_|TIMEOUT|GROUPS|FUNCNAME|DIRSTACK|PIPESTATUS|USERNAME|BASHPID|BASH_[A-Z_]+)' + } + _ignore_HARDCODED_ksh() { + # These names cannot be detected + echo '(_|TIMEOUT|IFS)' + } + _ignore_HARDCODED_zsh() { # These names cannot be detected echo '([-\?\#\!\$\*\@\_0]|zsh_eval_context|ZSH_EVAL_CONTEXT|LINENO|IFS|commands|functions|options|aliases|EUID|EGID|UID|GID|dis_patchars|patchars|terminfo|galiases|keymaps|parameters|jobdirs|dirstack|functrace|funcsourcetrace|zsh_scheduled_events|dis_aliases|dis_reswords|dis_saliases|modules|reswords|saliases|widgets|userdirs|historywords|nameddirs|termcap|dis_builtins|dis_functions|jobtexts|funcfiletrace|dis_galiases|builtins|history|jobstates|funcstack|run-help)' } _ignore_READONLY() { - typeset -pr | perl -e '@r = map { + _ignore_READONLY_$_shell_DIALECT + } + _parse_READONLY() { + # shellcheck disable=SC1078,SC1079,SC2026 + perl -e '@r = map { chomp; # sh on UnixWare: readonly TIMEOUT # ash: readonly var='val' @@ -73,6 +253,19 @@ env_parallel() { print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; ' } + _ignore_READONLY_sh() { + readonly | _parse_READONLY + } + _ignore_READONLY_bash() { + readonly | _parse_READONLY + } + _ignore_READONLY_ksh() { + readonly | _parse_READONLY + } + _ignore_READONLY_zsh() { + # shellcheck disable=SC3044 + typeset -pr | _parse_READONLY + } _remove_bad_NAMES() { # Do not transfer vars and funcs from env_parallel # shellcheck disable=SC2006 @@ -107,7 +300,7 @@ env_parallel() { _names_of_maybe_FUNCTIONS| _parallel_exit_CODE| _prefix_PARALLEL_ENV| - _prefix_PARALLEL_ENV| + _prefix_PARALLEL_ENV_bash| _remove_bad_NAMES| _remove_readonly| _variable_NAMES| @@ -121,6 +314,15 @@ env_parallel() { /^'"$_ignore_HARD"'$/ and next; print;' } + _prefix_PARALLEL_ENV_bash() { + # shellcheck disable=SC3044 + shopt 2>/dev/null | + perl -pe 's:\s+off:;: and s/^/shopt -u /; + s:\s+on:;: and s/^/shopt -s /; + s:;$:&>/dev/null;:'; + echo 'shopt -s expand_aliases &>/dev/null'; + } + _get_ignored_VARS() { perl -e ' for(@ARGV){ @@ -284,19 +486,49 @@ env_parallel() { fi unset _variable_NAMES - # shellcheck disable=SC2006 - PARALLEL_ENV="` + if $_eval_needed ; then + # shellcheck disable=SC2006 + PARALLEL_ENV="` + eval $_prefix_PARALLEL_ENV; eval $_list_alias_BODIES; - eval $_list_function_BODIES; + eval $_list_function_BODIES; eval $_list_variable_VALUES; - `" + `" + else + # shellcheck disable=SC2006 + PARALLEL_ENV="` + $_prefix_PARALLEL_ENV; + $_list_alias_BODIES; + $_list_function_BODIES; + $_list_variable_VALUES; + `" + fi export PARALLEL_ENV unset _list_alias_BODIES _list_variable_VALUES _list_function_BODIES unset _bodies_of_ALIASES _bodies_of_VARIABLES _bodies_of_FUNCTIONS unset _names_of_ALIASES _names_of_VARIABLES _names_of_FUNCTIONS unset _ignore_HARDCODED _ignore_READONLY _ignore_UNDERSCORE - unset _remove_bad_NAMES _grep_REGEXP + unset _remove_bad_NAMES _grep_REGEXP _parse_READONLY unset _prefix_PARALLEL_ENV + unset _ignore_READONLY_sh _ignore_READONLY_bash + unset _ignore_READONLY_ksh _ignore_READONLY_zsh + unset _ignore_HARDCODED_sh _ignore_HARDCODED_bash + unset _ignore_HARDCODED_ksh _ignore_HARDCODED_zsh + unset _bodies_of_ALIASES_ksh _bodies_of_ALIASES_sh + unset _bodies_of_ALIASES_zsh _bodies_of_FUNCTIONS_bash + unset _bodies_of_FUNCTIONS_ksh _bodies_of_FUNCTIONS_sh + unset _bodies_of_FUNCTIONS_zsh _bodies_of_VARIABLES_bash + unset _bodies_of_VARIABLES_ksh _bodies_of_VARIABLES_sh + unset _bodies_of_VARIABLES_zsh + unset _names_of_ALIASES _names_of_ALIASES_bash + unset _names_of_ALIASES_ksh _names_of_ALIASES_sh + unset _names_of_ALIASES_zsh _names_of_FUNCTIONS + unset _names_of_FUNCTIONS_bash _names_of_FUNCTIONS_ksh + unset _names_of_FUNCTIONS_sh _names_of_FUNCTIONS_zsh + unset _names_of_VARIABLES _names_of_VARIABLES_bash + unset _names_of_VARIABLES_ksh _names_of_VARIABLES_sh + unset _names_of_VARIABLES_zsh _names_of_maybe_FUNCTIONS + # Test if environment is too big by running 'true' # shellcheck disable=SC2006,SC2092 if `_which_PAR true` >/dev/null 2>/dev/null ; then @@ -387,7 +619,7 @@ _parset_main() { # Bash: declare -A myassoc=( ) # Zsh: typeset -A myassoc=( ) # Ksh: typeset -A myassoc=( ) - # shellcheck disable=SC2039,SC2169 + # shellcheck disable=SC2039,SC2169,SC3044 if (typeset -p "$_parset_NAME" 2>/dev/null; echo) | perl -ne 'exit not (/^declare[^=]+-A|^typeset[^=]+-A/)' ; then # This is an associative array diff --git a/testsuite/tests-to-run/parallel-local-0.3s.sh b/testsuite/tests-to-run/parallel-local-0.3s.sh index af96464a..970d4681 100644 --- a/testsuite/tests-to-run/parallel-local-0.3s.sh +++ b/testsuite/tests-to-run/parallel-local-0.3s.sh @@ -236,15 +236,17 @@ par_rpl_repeats() { par_do_not_export_PARALLEL_ENV() { echo '### Do not export $PARALLEL_ENV to children' + . env_parallel.bash + env_parallel --session doit() { echo Should be 0 echo "$PARALLEL_ENV" | wc echo Should give 60k and not overflow PARALLEL_ENV="$PARALLEL_ENV" parallel echo '{=$_="\""x$_=}' ::: 60000 | wc } - . env_parallel.bash # Make PARALLEL_ENV as big as possible - PARALLEL_ENV="a='$(seq 100000 | head -c $((139000-$(set|wc -c) )) )'" + PARALLEL_ENV="a='$(seq 100000 | head -c $((149000-$(set|wc -c) )) )'" + PARALLEL_ENV="a=b" env_parallel doit ::: 1 } @@ -608,6 +610,7 @@ par_expansion_in_colsep() { par_extglob() { bash -O extglob -c '. env_parallel.bash; + env_parallel --session _longopt () { case "$prev" in --+([-a-z0-9_])) diff --git a/testsuite/tests-to-run/parallel-local-1s.sh b/testsuite/tests-to-run/parallel-local-1s.sh index 1edb1a44..cfe997ef 100644 --- a/testsuite/tests-to-run/parallel-local-1s.sh +++ b/testsuite/tests-to-run/parallel-local-1s.sh @@ -951,7 +951,59 @@ par__test_cpu_detection_cpuinfo() { iyXJQ3TVfIX50ANedGFbHwEc/JQzJup4YQ== ' | unpack } - + cpu16() { + echo '2-12-24-12 Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz (vh4)' + echo ' + KLUv/QRoXSQA2kAECyUQTWMdEfORapSl6hpfhdTvIB2fCbydyAB94J9MxTuCiACAvIMbrACZ + AJ0AsZ09tMbz9g9R+7b4ZXza8a3rt/nrvhF6PwzyggEXWnj35HyVt0W7ehcKRhyyV5987THr + pbMZ/cgHndfuHbL2epFg40CDHwuibIXX30RjzViOxaAgKlVY4KBJonWzTdpeNNQLAHjkY97a + RoUFCo7EoG7gCPRDLYqAkuARHiCQcyVcAIQAG5k8AgCum9FYFvBFhriCmwG3SgYrn0KuAvcW + nU4uZBwvAIDO7m2TcisfdGzdal1fZePJXweaUUVXaSXbfdbc3Wv82Byfco2+pKidRcQfx/WR + 7d5HsR9F6JDbanc665MzPll6qzsFRwEqImz8J/mMp/zimXDyrNEhT3k357N46bs6b2f5ckYE + XV6JRtmqktWWsz3Cc+vq6J0nLTt+JA8ha73or8OP9TXx7qvtPu0I8SjGP27sXd0TrYAI2L4g + lfGhGe/9MFvot4tH1ATfzXjhzNpLJWgtrW25Lxemq3DjUjiGS3CdsoVtufiufAkpO3PvkW6i + Ola0NhuEq/KMFNo70r3ijX2VXnReWzGBOf004o4t9xh65f2iPjof5Wgh4i9K6AvTsUQvyvW1 + 77Dz3tR5d0731/ur/IWPfL0g+e7wvkIFQ6zosEe4EAkG7ySjjr4tCfEIYl+IdfRedrrx1RXM + 0SyIUphGKSQxKh2KMjSHapLD0iSGORpDWpBDUhTTNEmTDktiGKRJiqKWhCBJWZCUlDKkRKm0 + KAlRUpIgTHIkhTBKo5Q6HFJKSTFMYzgckJSOdCyIoWGQJSUFORblcEhSoyTLgjDHgiSJUkql + hlEMhyYlwyiwD5Msnu7CZAMyRaUPOiQf8K7P+dK91DlW5Ub5PMhWstw4NAakYRJ+cT7TMVhl + bi1ktdd8Mb6+xKtQEZcDa4DDqMFgxYzIjEiSgiQFSQfARoZG0yQHYsA0SQAhCAFCcIYihEFI + eEU4FDgnBg/CvfDTFEdfCnzKp/dGFGcRJTBac/VP682IZ7JNS8a8Qlfee2qAsyGbznwFCy/m + U1ALcxbXtKQvWrgyn3pamLNRTRuTMDy3ws1ZhXNbn0zs/KfjswDmAk60ueL78UwnwrzC2pwG + 8XKdA8G4QlXzjctfmU6/IHBeOaU+Mi2DiV5xvoW/1lQ9L8N6AE/hzUXgVu/lIk5iDv1pu4k5 + RtkHE4KPT2MhGjqcCQQPp9nTTpOA087fSVowhrBufLpp4ppGv6jkrAkYzqNwbyg8FOzwJTe/ + uFlcfjE0RytY1n2BzX1wHq3S3EPR87qJk8A3bdEymQU4if9RYRQUH0JH1v4o5Y+HZ4/Jcx+p + 6C67cHK/roV6KRX5eh5fZ5zfBAGIcypOQhRdDjoqorlsIRh4MyFFCa/+w9rnqQ9IhTJSxUEj + J/m5uPWXdiT61TaAn85i7vm/JHEVLykNoOaGbE6PZXMCHEOy4iJ6P6vgAOxE/spU7N53w3RU + pvPDpg6++vY602wMoPOM5mjPE/5E9C+1WNOag5ef9fYNxh+A4wfWolSv + ' | unpack + } + cpu17() { + echo '1-6-12-6 AMD Ryzen 5 4600G with Radeon Graphics (ai)' + echo ' + KLUv/QRoxSEA6kH0CiUwS1sdaPiIsqmQTVuLLykLrtQOna/tY8caFQPfvvvkgYUF54EBqgCc + AJkAyXde06cCxnbefuLRr7Zv8mG3a8dv81d9m/NWJGPGgWDrLLta7q3Iq8+i3saCmbNccbml + i/NALHx6KM3SarXOUlc3Gj4KJLiSHCKs/jaaeiAIIgBBDEkEBAsUkCTx6IO62pEo3GLe2Efr + ajjhgbu3Khm8iYvxAwiCMPxwtxEaDL4t3REKANiq145FabDVkvmC9TCwgICu6LaJCwJqIfiU + W+dAPgAAfN2rD3LJLXyKYNTHL341PirGIfQ7rTOcfm80LrOQGc+p5dvtFItlr/ZsKRNQm9Nv + aCqWIW6IaZJduYQKXhGJk18n+3lvPjrlx9+kPFcSZEAkjz4b82X7xeVe+4JaYIvGlL8cn3HC + NwYu55Hi5874uav3FIgXougytnv6xs7aUcEnRbKs+JEfis8+7oyldqMfmyvbfdgP86e1N71g + DNMjlhgOcq7LySv2ml7YRIYPN7LFbC+S37FXd656uupqdTbSXS5TlLQ5X5baSDse8YLuEJy+ + AxN7ZPeYMK/MeuW49VxifAFZwcPIcOH6gxuB6WMs44uopcYL1Zc4Ka7iuS6HsuknBlPO1n9U + Xu12oragV3hbX0lWS9/O1IpmWnMe+4kbpvVM7SrFjM2I0bDSLwzF1CfWP3Elo10Z4/RLkiSH + REEhQeFwSCxLQpIgCMQhSQ6HBRFwQCyJIZEwLMoiAFmSZTEYFEVRkuQ4HhgeLImDP4gWFjKI + YZbRvMVzjO/4AS7b4TIeHywXES4nwDuu9IShe6FSGd02ZEAcvYrkJzBcSUCWAgoaHAqJhObV + nuKl4zXsp4YotmYpLnx3ciO92EhJYHzDGBN1o7iwG71IR2rrw6e66DtPFyLGYwxc510tXm1x + BqMiXW5mKZyrfKwFgKGowTykkDGkRkRGZKRJOoBExqg4GQ5COUGLMEUERrgzJMbE/0wgQaYH + 7rSgB1fM/kMSWx8VlA5S0OKNuWI8OR/359dtGFxgAconnVldLp+9a9V7SFk+bs+OtlyqzwrK + xcHda6arrSv0SUHpjILKezeeFaB80pjp9b4rw/lQiyR/K5yP+vP9LYeOwRWAt+ciFnSiLUur + rq4cAM/MprXU19jHLpLvmiWBe6zHzaIqO1sZ35yOXlqIa29j88LhLeMSOPNflUdcL2cNG6ti + NPWjEbKXtIVeflMMLyjsWLuCUcxPFBWGmna3DgpIJmairUxU9OPb1XINMjCrs+PJbgrQARvc + 19rY5t2tN8ulUxMyLr9RA4/vay9o8CfTq00/5AalMO6Kxg8B8HlNZ18ej/83Xw8IP+brlaoW + nemRDRyMrTRoNR6FdbT66kV1nQt2zfQ7krZmj6IJ9/O6aXGMPXcancqeawY7QJtwnNUtOMQ0 + DPeXb9dzDOgUh0ST3w== + ' | unpack + } export -f $(compgen -A function | grep ^cpu) test_one() { @@ -1149,6 +1201,63 @@ par__test_cpu_detection_lscpu() { oiCpQLqitFXU0Fyo+a4q4SvbmVMCr0burQ== ' | unpack } + cpu16() { + echo '2-12-24-12 Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz (vh4)' + echo ' + KLUv/QRovSMA6kiMDCngcIhzFH4Td8ruJqLZFq6rg/LAmM8J4PRtw8ZYAfijNgkAOE2YISXG + hNQAwgCwABJRul4TTmKBFGhoFCDgoDw4TGQkJUx0jAYGo2lUCw5oIA2QAgwz4WDSRNHtalOW + CQcNGI6G5gfeoM5oHs1iwIIotcIDQABQuOIbT5ucLI/Kc3BB144OGt0UtYECh0/ZokrEI5hM + iLA0lOXReoFJ1ikTLI1kn7pt6ZQilkazYDS792t0bxElLI7mramnoyCOK95ijivSnts9fzhY + JxyfWWdrCJa4XIsLrq/bQZjapoRrVySL43FFu2fRNAIwAG0SLlZ+wkOCxfFwHpDqEZ1TM20n + sYkgc67nHO3KwAIqK9lUniIMdZ29UDKm/BbXX7O5X456Y9cuoVwp1+tNEea1lec6ZfOZLqWp + vqcVIqJvNV866JBBtn5qgKdC0PTMpS/BI9wm+qhHTChXsEo8PehvuRYle4WJBE+losMXRDzc + ANQMBNZo7TWapC8lcu0mj0wkHjjJ9Zvgn9cOTZspBK23jPAWLv7q1T5V6tXglXbPPWtqfJME + hFEwzOLBEGAWDaMYsGCcwWhM3jiJe3AHpKESW+yNgbBUi4h3PFi7HUPD8Cb42N7F/Xpz07KV + 8ZVIPrmyq7+V8U3KyFmd537Oj+6jhNDUdSQ2l9NxNcP3Zdxt/okY3bav4t9bjCt8ffaw39KZ + 3yjzJ1fQKwjvlq1ztz/2R6PXnpKQfUX7ORt+lc/crkMqdmXwuvaT4Rn3lffarpD6tNAjHK3H + INJTPussVni94ohn6kLycMVz0CUUiAjKFRQYOBQIyYPEIbont2kXF39qRyf3jsNTXUtjnsOc + Bs+9j2+ur+YOp0rddmJMsvecXgkxsDOc+mYV8hvGwefNk4W2lNfDEUNvy2luqffqlG5upQ+6 + g5F6BtmWxM7cfvOffdx5Pu7tYX50u867672+KDp2qOj+rL7ftCAHPuvwOZC03mzz7MFAr6h1 + pRZXZ12fCl07bWlzOrKVe30oCZvqDeM4lPmLtTfH9pC1/dyu/mAq9gWhR0/jN5RZ+RWk/pY5 + 3D5luyhhgIsgQIQYg8joAUWIgGFyHo+2H9H0VAgUhrODQJiKFAXV8DW+RBm3SVsDCbC8Bq07 + KGXGx0zhrEhoL0TC+UumTeUY9jUCrBkKh/0502187xaJLlwUWm0uUXXytESfDgGEb4NkqRnw + hh6SeWGWHUwwKJLAJgOwcJUAICETFDQ9MStQHwsQlNeVyIXBLgwRq/f1bAUN4i6zXZkAGNbF + r4UWmZ8oYXG08h4R4SqgQ6xUaE5ULo1bw9Cx8rk6OS10SMFLxNtSqZeTOx8HMOMzSrwtUXV6 + BdvV5WraGwmfuVpoygqX6zRBbFeLmaObBRLPgJFBqKCMJobTUMYomLcjxSwECvUOqMBBukMM + 4bbPXtAAm2D9K7ytqjEnBktqmyprOEzwz3FpK3A7w6IQoSGMJHxRorxI5ZT116mlsbsI0wBc + tYwCxsaqkbWS1O8AhakwClACiAG09g== + ' | unpack + } + cpu17() { + echo '1-6-12-6 AMD Ryzen 5 4600G with Radeon Graphics (ai)' + echo ' + KLUv/QRoDScASlLADSnwjGjbQLXf7SEiYhXDl17bzy9x/Sd+rgMwdzVDfBFY6exTLCwOI7dP + BeMAxADHALmu6P54Pbmv7K7puqJDzmEKqgUMAw4FJhIRkkZpEA0NtgwCGBgKPCIXDSS34Eqq + GmTa3FrzSzKFLPQteITC1jntCaMxYUBaK7KxvoaA4Wj5py6hvoeCATHwh+OidqHDuY/Dx+Cs + acKJP72VM2BggDScwJleXCauC9mVpiZhJJA85DbTp6GHBBF/LTGdwGg0FhiaV/3KVi2wCAxH + g+EmpuCquvfB0/QiXPsCwVAI9dtIQWEuXx53vkMD68XymfWl9MBogFyht1lwPAIwAE1tLbh2 + CRIIGA0QBuJgeUQf1Km9T76HTGO+cXlLL1bWUynXvGH6WjKvs7nW1+x3qryXbQWfm30l4vYn + Wx19rtJYelyZGWUV8q7jatDh5Yr4l0SKKsYtxnlQPTF86T0hjQivEbLlrPhm6Zq7Ng7LHQ2m + AdKw5HE5fyi3XtbWLZKFgpZK92XuyuH7cp46ZFJb9Gkhl66xK9fYU2sUxuljmmEza/ml7pI7 + vTeUhrrk3q4xbVELu1KYfOH3c4cy/7HFuWWtPwwpR+Uhj0b3qK08Utzf63Wn/FyHd7DkNY4N + wJp7CIBDrIM7DOiTmE+NB4wJC6xt48VOYGCuTIgftdTHVJpynkbtad0u6Op1MqmOnaVET9jU + ipjouRE+qfawvqcd96et1lGG0J2blxk1tdT0tIyX5gxVJdPkiq4KkxnG7WOviPjRa9TbsTc+ + fDqXTxHbxprKoefS+2v39O3b0wuVTSns1sxqloMyWyNqWimW5zIGH35TUelw8S0Jn1Q5vSOz + LPIOp4vvaOxqrowNU9hZK3ozv2aPzXpqmK+NzY6pPC7lHyqRfq3BJ7sw3sIUzZtE6AKExBXU + OoeYTFyBtQW+YEWhgsJNrOUhrsDKVjXn6GXIf9psmzvD8NN9D5szxWGFB1xcy6ccaUTX1261 + TOUnhledzx034k2HmFyjbVQQo7s019eaKRRMXB3kSEVi83uqm6R2e+4SEBEUEwrJ5AcqGPT0 + 2YNa35OyxdcM+gHK9kqSqmpaJyKqsPltV4RVWmqlj3CSON14sM+2gtYb1RFJO9Vx8N0gKLeQ + j43pT59GBr/0qm3wKVPQGRo/+4NEAgSHw0PyxwOAmCBQhAwZGbcBSJYmAyLVG/5ngAQMQSDK + NQS2pztrYwEu8wFcfeyBYD2uRC8cu9AcDJpOjLQh7rL0Fa7gA0e/PKc048NKtpjWvTy15IMc + q4uFsqler/RyxCH4EQ5D3JoKmIAzHQMGrkiUOpngtr7yKtD1Ck60jerH1Pl5YDli1yPO8eqT + dYGslS4vjnB2tgEI3t9gKaN5ajSqBQofOAWAYQioyBfyMNvbjJC3koCWTuO1A+XEl66LWhlg + zo5pwC8w9OjdaAMFpEBr8cSA+xrfFV0kAXQEhFBoqWCE5A+s4GostEFs069Tkyc460L7alvL + t0B7CQA+l6gZpkZywzEQATxYpIrZvtZvFY+NmLQ76NZvhd72aVyhHWrGgMXCoonW7dgxy4Bi + wCsuGJB+NTPEBrEagkv08IyA+ScYD9t1ilA7hp3bMj0LvwaAVXZjIVR3U0thpwhTAXBxv2tg + gAplMV0DrnilFovCKIxyldJcA2k= + ' | unpack + } + export -f $(compgen -A function | grep ^cpu) test_one() { diff --git a/testsuite/tests-to-run/parallel-local-ssh7.sh b/testsuite/tests-to-run/parallel-local-ssh7.sh index d7707879..3dfc22dd 100755 --- a/testsuite/tests-to-run/parallel-local-ssh7.sh +++ b/testsuite/tests-to-run/parallel-local-ssh7.sh @@ -1720,11 +1720,11 @@ _EOF par_environment_too_big_bash() { myscript=$(cat <<'_EOF' echo 'bug #50815: env_parallel should warn if the environment is too big' - len_overhead=-10-$( (shopt;alias;typeset -f;typeset -p) | wc -c)/1000 + len_overhead=-20-$( (shopt;alias;typeset -f;typeset -p) | wc -c)/1000 len_var=$len_overhead+56 len_var_remote=$len_overhead+40 - len_var_quote=$len_overhead+31 - len_var_quote_remote=$len_overhead+22 + len_var_quote=$len_overhead+41 + len_var_quote_remote=$len_overhead+32 len_fun=$len_overhead+56 len_fun_remote=$len_overhead+40 len_fun_quote=$len_overhead+56 @@ -1870,8 +1870,8 @@ par_environment_too_big_fish() { par_environment_too_big_ksh() { myscript=$(cat <<'_EOF' echo 'bug #50815: env_parallel should warn if the environment is too big' - len_functions=-$(functions|wc -c)/1000 - len_variables=-$(typeset -p | wc -c)/1000 + len_functions=-15-$(functions|wc -c)/1000 + len_variables=-15-$(typeset -p | wc -c)/1000 len_var=$len_variables+40 len_var_remote=$len_variables+30 len_var_quote=$len_variables+43 @@ -1942,10 +1942,10 @@ _EOF par_environment_too_big_mksh() { myscript=$(cat <<'_EOF' echo 'bug #50815: env_parallel should warn if the environment is too big' - len_var=46 - len_var_remote=31 - len_var_quote=46 - len_var_quote_remote=31 + len_var=46-15 + len_var_remote=$len_var-15 + len_var_quote=$len_var + len_var_quote_remote=$len_var-15 len_fun=28 len_fun_remote=13 len_fun_quote=28 diff --git a/testsuite/tests-to-run/parallel-local-ssh9.sh b/testsuite/tests-to-run/parallel-local-ssh9.sh index f895b365..b8555c00 100644 --- a/testsuite/tests-to-run/parallel-local-ssh9.sh +++ b/testsuite/tests-to-run/parallel-local-ssh9.sh @@ -153,10 +153,11 @@ par__propagate_env() { par_env_parallel_big_env() { echo '### bug #54128: command too long when exporting big env' - . `which env_parallel.bash` - a=`rand | perl -pe 's/\0//g'| head -c 15000` + . env_parallel.bash + env_parallel --session + a=`rand | perl -pe 's/\0//g'| head -c 40000` env_parallel -Slo echo should not ::: fail 2>&1 - a=`rand | perl -pe 's/\0//g'| head -c 25000` + a=`rand | perl -pe 's/\0//g'| head -c 45000` env_parallel -Slo echo should ::: fail 2>/dev/null || echo OK } @@ -235,6 +236,8 @@ par_sshlogin_range() { } doit -S a[000-123].nx-dom,b[2,3,5,7-11]c[1,4,6].nx-dom doit -S{prod,dev}[000-100].nx-dom + doit -S'2[49-51].0.[9-11].1[09-11]' + } export -f $(compgen -A function | grep par_) diff --git a/testsuite/tests-to-run/parallel-local150.sh b/testsuite/tests-to-run/parallel-local150.sh index 3a367909..c7ffef05 100644 --- a/testsuite/tests-to-run/parallel-local150.sh +++ b/testsuite/tests-to-run/parallel-local150.sh @@ -14,7 +14,7 @@ echo '### Bug in --load'; nice parallel -k --load 30 sleep 0.1\;echo ::: 1 2 3 echo '### Test --timeout' - nice parallel -j0 -k --timeout 2 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9 + nice stdout parallel -j0 -k --timeout 2 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9 echo '### Test --joblog followed by --resume --joblog' rm -f /tmp/joblog; diff --git a/testsuite/wanted-results/parallel-local-1s b/testsuite/wanted-results/parallel-local-1s index 206aaf25..c5e1dcf3 100644 --- a/testsuite/wanted-results/parallel-local-1s +++ b/testsuite/wanted-results/parallel-local-1s @@ -280,6 +280,10 @@ par__test_cpu_detection_cpuinfo 1-1-1-1 Intel Xeon X5675 (mandriva.p) par__test_cpu_detection_cpuinfo 1 1 1 1 par__test_cpu_detection_cpuinfo 1-1-1-1 Intel(R) Celeron(R) M (eee900) par__test_cpu_detection_cpuinfo 1 1 1 1 +par__test_cpu_detection_cpuinfo 2-12-24-12 Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz (vh4) +par__test_cpu_detection_cpuinfo 2 12 24 12 +par__test_cpu_detection_cpuinfo 1-6-12-6 AMD Ryzen 5 4600G with Radeon Graphics (ai) +par__test_cpu_detection_cpuinfo 1 6 12 6 par__test_cpu_detection_cpuinfo 1-4-8-4 Core i7-3632QM Acer laptop par__test_cpu_detection_cpuinfo 1 4 8 4 par__test_cpu_detection_cpuinfo 1-2-4-2 Core i5-2410M laptop firewall @@ -306,6 +310,10 @@ par__test_cpu_detection_lscpu 1-1-1-1 Intel Xeon X5675 (mandriva.p) par__test_cpu_detection_lscpu 1 1 1 1 par__test_cpu_detection_lscpu 1-1-1-1 Intel(R) Celeron(R) M (eee900) par__test_cpu_detection_lscpu 1 1 1 1 +par__test_cpu_detection_lscpu 2-12-24-12 Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz (vh4) +par__test_cpu_detection_lscpu 2 12 24 12 +par__test_cpu_detection_lscpu 1-6-12-6 AMD Ryzen 5 4600G with Radeon Graphics (ai) +par__test_cpu_detection_lscpu 1 6 12 6 par__test_cpu_detection_lscpu 1-4-8-4 Core i7-3632QM Acer laptop par__test_cpu_detection_lscpu 1 4 8 4 par__test_cpu_detection_lscpu 1-2-4-2 Core i5-2410M laptop firewall diff --git a/testsuite/wanted-results/parallel-local-ssh7 b/testsuite/wanted-results/parallel-local-ssh7 index aef1b89c..e6887752 100644 --- a/testsuite/wanted-results/parallel-local-ssh7 +++ b/testsuite/wanted-results/parallel-local-ssh7 @@ -547,9 +547,9 @@ par__man_ksh work, par__man_ksh too par__man_ksh This may never work par__man_ksh https://unix.stackexchange.com/questions/457031/extract-full-function-definitions -par__man_ksh /bin/ksh: line 3: syntax error at line 99: `{' unmatched -par__man_ksh /bin/ksh: line 3: syntax error at line 99: `{' unmatched -par__man_ksh /bin/ksh: line 3: syntax error at line 99: `{' unmatched +par__man_ksh /bin/ksh: line 99: syntax error at line 99: `{' unmatched +par__man_ksh /bin/ksh: line 99: syntax error at line 99: `{' unmatched +par__man_ksh /bin/ksh: line 99: syntax error at line 99: `{' unmatched par__man_ksh exit value 2 should be 2 par__man_ksh Unknown option: no-such-option par__man_ksh exit value 255 should be 255 @@ -1230,10 +1230,10 @@ par_env_parallel_--session_ksh l2var par_env_parallel_--session_ksh l2func par_env_parallel_--session_ksh l2alias par_env_parallel_--session_ksh level2 array OK -par_env_parallel_--session_ksh /bin/ksh: line 3: aliasbefore: not found -par_env_parallel_--session_ksh script: line 4: aliasbefore: not found -par_env_parallel_--session_ksh /bin/ksh: line 3: funcbefore: not found -par_env_parallel_--session_ksh script: line 4: funcbefore: not found +par_env_parallel_--session_ksh /bin/ksh: line 2: aliasbefore: not found +par_env_parallel_--session_ksh script: line 3: aliasbefore: not found +par_env_parallel_--session_ksh /bin/ksh: line 2: funcbefore: not found +par_env_parallel_--session_ksh script: line 3: funcbefore: not found par_env_parallel_--session_ksh no_before par_env_parallel_--session_ksh no_before par_env_parallel_--session_ksh no_before diff --git a/testsuite/wanted-results/parallel-local-ssh9 b/testsuite/wanted-results/parallel-local-ssh9 index 3cfe1203..1e17a7bc 100644 --- a/testsuite/wanted-results/parallel-local-ssh9 +++ b/testsuite/wanted-results/parallel-local-ssh9 @@ -380,6 +380,34 @@ par_sshlogin_range parallel: Warning: Could not figure out number of cpus on pro par_sshlogin_range parallel: Warning: Could not figure out number of cpus on prod098.nx-dom (). Using 1. par_sshlogin_range parallel: Warning: Could not figure out number of cpus on prod099.nx-dom (). Using 1. par_sshlogin_range parallel: Warning: Could not figure out number of cpus on prod100.nx-dom (). Using 1. +par_sshlogin_range echo 1 +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.10.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.10.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.10.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.11.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.11.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.11.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.9.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.9.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 249.0.9.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.10.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.10.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.10.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.11.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.11.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.11.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.9.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.9.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 250.0.9.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.10.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.10.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.10.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.11.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.11.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.11.111 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.9.109 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.9.110 (). Using 1. +par_sshlogin_range parallel: Warning: Could not figure out number of cpus on 251.0.9.111 (). Using 1. par_sh_embed --embed par_sh_embed Redirect the output to a file and add your changes at the end: par_sh_embed /usr/local/bin/parallel --embed > new_script diff --git a/testsuite/wanted-results/parallel-local150 b/testsuite/wanted-results/parallel-local150 index ac6f0738..d8a96fd2 100644 --- a/testsuite/wanted-results/parallel-local150 +++ b/testsuite/wanted-results/parallel-local150 @@ -5,11 +5,17 @@ echo '### Bug in --load'; nice parallel -k --load 30 sleep 0.1\;echo ::: 1 2 3 3 echo '### Test --timeout' ### Test --timeout - nice parallel -j0 -k --timeout 2 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9 + nice stdout parallel -j0 -k --timeout 2 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9 1.1 1.1 +parallel: Warning: This job was killed because it timed out: +parallel: Warning: echo 7.7; sleep 7.7; echo 7.7 7.7 +parallel: Warning: This job was killed because it timed out: +parallel: Warning: echo 8.8; sleep 8.8; echo 8.8 8.8 +parallel: Warning: This job was killed because it timed out: +parallel: Warning: echo 9.9; sleep 9.9; echo 9.9 9.9 echo '### Test --joblog followed by --resume --joblog' ### Test --joblog followed by --resume --joblog diff --git a/testsuite/wanted-results/parallel-macos b/testsuite/wanted-results/parallel-macos index ef9ed259..b621a2fe 100644 --- a/testsuite/wanted-results/parallel-macos +++ b/testsuite/wanted-results/parallel-macos @@ -1,46 +1,81 @@ -par_big_func 1 3XXX 91XXX -par_big_func 1 3XXX 91XXX -par_big_func 1 3XXX 91XXX -par_big_func 1 1XXX 46XXX -par_many_args 1 3XXX 6XXX -par_many_args 1 3XXX 6XXX -par_many_args 1 3XXX 6XXX -par_many_args 1 3XXX 6XXX -par_many_args 1 3XXX 6XXX -par_many_args 1 3XXX 6XXX -par_many_args 1 1XXX 2XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 212 5XXX -par_many_func 1 96 2XXX +par_big_func 1 3XXX 90XXX +par_big_func 1 3XXX 90XXX +par_big_func 1 3XXX 90XXX +par_big_func 1 2XXX 48XXX +par_big_func_name 18XXX +par_big_func_name 18XXX +par_big_func_name 18XXX +par_big_func_name 18XXX +par_big_func_name 18XXX +par_big_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_big_var_func_name 18XXX +par_many_args 1 2XXX 5XXX +par_many_args 1 2XXX 5XXX +par_many_args 1 2XXX 5XXX +par_many_args 1 2XXX 5XXX +par_many_args 1 2XXX 5XXX +par_many_args 1 2XXX 5XXX +par_many_args 1 2XXX 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 184 4XXX +par_many_func 1 44 1XXX +par_many_var 22XXX +par_many_var 22XXX +par_many_var 22XXX +par_many_var 22XXX +par_many_var 22XXX +par_many_var 22XXX +par_many_var 22XXX par_many_var_big_func 5XXX par_many_var_big_func 5XXX par_many_var_big_func 5XXX @@ -68,6 +103,9 @@ par_many_var_big_func 5XXX par_many_var_big_func 5XXX par_many_var_big_func 5XXX par_many_var_big_func 5XXX -par_many_var_func 1 2XXX 59XXX -par_many_var_func 1 2XXX 59XXX -par_many_var_func 1 1XXX 41XXX +par_many_var_big_func 5XXX +par_many_var_big_func 5XXX +par_many_var_big_func 5XXX +par_many_var_func 1 2XXX 58XXX +par_many_var_func 1 2XXX 58XXX +par_many_var_func 1 1XXX 43XXX