From bcdea235697e9c6fc14932f7f24860a37c02ffbd Mon Sep 17 00:00:00 2001 From: Ole Tange Date: Wed, 8 Feb 2017 00:54:45 +0100 Subject: [PATCH] env_parallel.{ash,dash}: added. Only aliases and variables are supported. --- Makefile.am | 56 ++++++++++++++++ Makefile.in | 56 ++++++++++++++++ NEWS | 5 ++ README | 12 ++-- configure | 20 +++--- configure.ac | 2 +- src/Makefile.am | 20 +++--- src/Makefile.in | 20 +++--- src/env_parallel | 49 ++++++++++---- src/env_parallel.ash | 145 +++++++++++++++++++++++++++++++++++++++++ src/env_parallel.dash | 145 +++++++++++++++++++++++++++++++++++++++++ src/env_parallel.pod | 89 +++++++++++++++++++++++++ src/niceload | 2 +- src/parallel | 2 +- src/parallel.pod | 5 ++ src/sql | 2 +- testsuite/REQUIREMENTS | 4 +- 17 files changed, 580 insertions(+), 54 deletions(-) create mode 100644 src/env_parallel.ash create mode 100755 src/env_parallel.dash diff --git a/Makefile.am b/Makefile.am index 8bef00a4..0dd1fc43 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,4 +59,60 @@ upload: pushd; \ sudo cp /usr/local/bin/parallel /usr/local/bin/parallel-$(YYYYMMDD) +alphaupload: +# Copy of upload + eval `gpg-agent --daemon` +# make sure $YYYYMMDD is set + echo $(YYYYMMDD) | grep 20 + cp parallel-$(YYYYMMDD).tar.bz2 parallel-latest.tar.bz2 + cp doc/parallel.directive parallel-$(YYYYMMDD).tar.bz2.directive + perl -i -pe "s/20\d\d\d\d\d\d/$(YYYYMMDD)/" parallel-*.tar.*directive + gpg --clearsign --yes parallel-$(YYYYMMDD).tar.bz2.directive + + cp doc/parallel.latest.directive parallel-latest.tar.bz2.directive + perl -i -pe "s/20\d\d\d\d\d\d/$(YYYYMMDD)/" parallel-latest.tar.*directive + gpg --clearsign --yes parallel-latest.tar.bz2.directive + + (echo '#!/bin/bash'; \ + echo; \ + echo "# To check the signature run:"; \ + echo "# echo | gpg"; \ + echo "# gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-$(YYYYMMDD).tar.bz2.sig"; \ + echo; \ + echo "echo | gpg 2>/dev/null"; \ + echo 'gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve $$0'; \ + echo 'exit $$?' ; \ + echo; \ + gpg -ab -o - parallel-$(YYYYMMDD).tar.bz2; \ + ) > parallel-$(YYYYMMDD).tar.bz2.sig + + (echo '#!/bin/bash'; \ + echo; \ + echo "# To check the signature run:"; \ + echo "# echo | gpg"; \ + echo "# gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-latest.tar.bz2.sig"; \ + echo; \ + echo "echo | gpg 2>/dev/null"; \ + echo 'gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve $$0'; \ + echo 'exit $$?' ; \ + echo; \ + gpg -ab -o - parallel-$(YYYYMMDD).tar.bz2; \ + ) > parallel-latest.tar.bz2.sig + + gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-latest.tar.bz2.sig + gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-$(YYYYMMDD).tar.bz2.sig + + ../ftpsync/src/ftpsync parallel-$(YYYYMMDD).tar.bz2{,.sig,*asc} ftp://ftp-upload.gnu.org/incoming/alpha/ + +# This can take 7 minutes + pushd /tmp; \ + rm -rf /tmp/parallel-$(YYYYMMDD)*; \ + while ! wget http://alpha.gnu.org/gnu/parallel/parallel-$(YYYYMMDD).tar.bz2 ; do sleep 2; done; \ + tar xjvf parallel-$(YYYYMMDD).tar.bz2; \ + cd parallel-$(YYYYMMDD); \ + ./configure; \ + make -j && sudo make -j install; \ + pushd; \ + sudo cp /usr/local/bin/parallel /usr/local/bin/parallel-$(YYYYMMDD) + EXTRA_DIST = CITATION CREDITS diff --git a/Makefile.in b/Makefile.in index fb1a5d29..12809a15 100644 --- a/Makefile.in +++ b/Makefile.in @@ -807,6 +807,62 @@ upload: pushd; \ sudo cp /usr/local/bin/parallel /usr/local/bin/parallel-$(YYYYMMDD) +alphaupload: +# Copy of upload + eval `gpg-agent --daemon` +# make sure $YYYYMMDD is set + echo $(YYYYMMDD) | grep 20 + cp parallel-$(YYYYMMDD).tar.bz2 parallel-latest.tar.bz2 + cp doc/parallel.directive parallel-$(YYYYMMDD).tar.bz2.directive + perl -i -pe "s/20\d\d\d\d\d\d/$(YYYYMMDD)/" parallel-*.tar.*directive + gpg --clearsign --yes parallel-$(YYYYMMDD).tar.bz2.directive + + cp doc/parallel.latest.directive parallel-latest.tar.bz2.directive + perl -i -pe "s/20\d\d\d\d\d\d/$(YYYYMMDD)/" parallel-latest.tar.*directive + gpg --clearsign --yes parallel-latest.tar.bz2.directive + + (echo '#!/bin/bash'; \ + echo; \ + echo "# To check the signature run:"; \ + echo "# echo | gpg"; \ + echo "# gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-$(YYYYMMDD).tar.bz2.sig"; \ + echo; \ + echo "echo | gpg 2>/dev/null"; \ + echo 'gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve $$0'; \ + echo 'exit $$?' ; \ + echo; \ + gpg -ab -o - parallel-$(YYYYMMDD).tar.bz2; \ + ) > parallel-$(YYYYMMDD).tar.bz2.sig + + (echo '#!/bin/bash'; \ + echo; \ + echo "# To check the signature run:"; \ + echo "# echo | gpg"; \ + echo "# gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-latest.tar.bz2.sig"; \ + echo; \ + echo "echo | gpg 2>/dev/null"; \ + echo 'gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve $$0'; \ + echo 'exit $$?' ; \ + echo; \ + gpg -ab -o - parallel-$(YYYYMMDD).tar.bz2; \ + ) > parallel-latest.tar.bz2.sig + + gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-latest.tar.bz2.sig + gpg --auto-key-locate keyserver --keyserver-options auto-key-retrieve parallel-$(YYYYMMDD).tar.bz2.sig + + ../ftpsync/src/ftpsync parallel-$(YYYYMMDD).tar.bz2{,.sig,*asc} ftp://ftp-upload.gnu.org/incoming/alpha/ + +# This can take 7 minutes + pushd /tmp; \ + rm -rf /tmp/parallel-$(YYYYMMDD)*; \ + while ! wget http://alpha.gnu.org/gnu/parallel/parallel-$(YYYYMMDD).tar.bz2 ; do sleep 2; done; \ + tar xjvf parallel-$(YYYYMMDD).tar.bz2; \ + cd parallel-$(YYYYMMDD); \ + ./configure; \ + make -j && sudo make -j install; \ + pushd; \ + sudo cp /usr/local/bin/parallel /usr/local/bin/parallel-$(YYYYMMDD) + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/NEWS b/NEWS index 6a8eba2c..4c19fb5a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +20170206alpha + +* --tee introduced. + + 20170122 * sql now uses a temporary credentials file for MySQL to avoid diff --git a/README b/README index 9ffd0de1..dab1a946 100644 --- a/README +++ b/README @@ -44,9 +44,9 @@ document. Full installation of GNU Parallel is as simple as: - wget http://ftpmirror.gnu.org/parallel/parallel-20170122.tar.bz2 - bzip2 -dc parallel-20170122.tar.bz2 | tar xvf - - cd parallel-20170122 + wget http://ftpmirror.gnu.org/parallel/parallel-20170206.tar.bz2 + bzip2 -dc parallel-20170206.tar.bz2 | tar xvf - + cd parallel-20170206 ./configure && make && sudo make install @@ -55,9 +55,9 @@ Full installation of GNU Parallel is as simple as: If you are not root you can add ~/bin to your path and install in ~/bin and ~/share: - wget http://ftpmirror.gnu.org/parallel/parallel-20170122.tar.bz2 - bzip2 -dc parallel-20170122.tar.bz2 | tar xvf - - cd parallel-20170122 + wget http://ftpmirror.gnu.org/parallel/parallel-20170206.tar.bz2 + bzip2 -dc parallel-20170206.tar.bz2 | tar xvf - + cd parallel-20170206 ./configure --prefix=$HOME && make && make install Or if your system lacks 'make' you can simply copy src/parallel diff --git a/configure b/configure index 9f9095d1..435ab796 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for parallel 20170122. +# Generated by GNU Autoconf 2.69 for parallel 20170206. # # Report bugs to . # @@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='parallel' PACKAGE_TARNAME='parallel' -PACKAGE_VERSION='20170122' -PACKAGE_STRING='parallel 20170122' +PACKAGE_VERSION='20170206' +PACKAGE_STRING='parallel 20170206' PACKAGE_BUGREPORT='bug-parallel@gnu.org' PACKAGE_URL='' @@ -1214,7 +1214,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures parallel 20170122 to adapt to many kinds of systems. +\`configure' configures parallel 20170206 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1281,7 +1281,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of parallel 20170122:";; + short | recursive ) echo "Configuration of parallel 20170206:";; esac cat <<\_ACEOF @@ -1357,7 +1357,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -parallel configure 20170122 +parallel configure 20170206 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1374,7 +1374,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by parallel $as_me 20170122, which was +It was created by parallel $as_me 20170206, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2237,7 +2237,7 @@ fi # Define the identity of the package. PACKAGE='parallel' - VERSION='20170122' + VERSION='20170206' cat >>confdefs.h <<_ACEOF @@ -2880,7 +2880,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by parallel $as_me 20170122, which was +This file was extended by parallel $as_me 20170206, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2942,7 +2942,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -parallel config.status 20170122 +parallel config.status 20170206 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 01ad29c0..b588ca17 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([parallel], [20170122], [bug-parallel@gnu.org]) +AC_INIT([parallel], [20170206], [bug-parallel@gnu.org]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ diff --git a/src/Makefile.am b/src/Makefile.am index 6f47b5da..0742d208 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,7 @@ -bin_SCRIPTS = parallel sql niceload parcat \ - env_parallel env_parallel.bash env_parallel.zsh env_parallel.fish \ - env_parallel.ksh env_parallel.pdksh env_parallel.csh env_parallel.tcsh +bin_SCRIPTS = parallel sql niceload parcat env_parallel \ + env_parallel.ash env_parallel.bash env_parallel.csh \ + env_parallel.dash env_parallel.fish env_parallel.ksh \ + env_parallel.pdksh env_parallel.tcsh env_parallel.zsh install-exec-hook: rm $(DESTDIR)$(bindir)/sem || true @@ -228,9 +229,10 @@ DISTCLEANFILES = parallel.1 env_parallel.1 sem.1 sql.1 niceload.1 \ parallel_tutorial.pdf parallel_design.pdf parallel_alternatives.pdf \ parcat.pdf -EXTRA_DIST = parallel sem sql niceload parcat env_parallel \ - env_parallel.bash env_parallel.zsh env_parallel.fish env_parallel.ksh \ - env_parallel.pdksh env_parallel.csh env_parallel.tcsh \ - sem.pod parallel.pod env_parallel.pod niceload.pod parallel_tutorial.pod \ - parallel_design.pod parallel_alternatives.pod \ - $(DISTCLEANFILES) +EXTRA_DIST = parallel sem sql niceload parcat env_parallel \ + env_parallel.ash env_parallel.bash env_parallel.csh \ + env_parallel.dash env_parallel.fish env_parallel.ksh \ + env_parallel.pdksh env_parallel.tcsh env_parallel.zsh \ + sem.pod parallel.pod env_parallel.pod niceload.pod \ + parallel_tutorial.pod parallel_design.pod \ + parallel_alternatives.pod $(DISTCLEANFILES) diff --git a/src/Makefile.in b/src/Makefile.in index 2fa5e1c7..5b26de2a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -229,9 +229,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -bin_SCRIPTS = parallel sql niceload parcat \ - env_parallel env_parallel.bash env_parallel.zsh env_parallel.fish \ - env_parallel.ksh env_parallel.pdksh env_parallel.csh env_parallel.tcsh +bin_SCRIPTS = parallel sql niceload parcat env_parallel \ + env_parallel.ash env_parallel.bash env_parallel.csh \ + env_parallel.dash env_parallel.fish env_parallel.ksh \ + env_parallel.pdksh env_parallel.tcsh env_parallel.zsh @DOCUMENTATION_TRUE@man_MANS = parallel.1 env_parallel.1 sem.1 sql.1 niceload.1 \ @DOCUMENTATION_TRUE@ parallel_tutorial.7 parallel_design.7 parallel_alternatives.7 \ @@ -260,12 +261,13 @@ DISTCLEANFILES = parallel.1 env_parallel.1 sem.1 sql.1 niceload.1 \ parallel_tutorial.pdf parallel_design.pdf parallel_alternatives.pdf \ parcat.pdf -EXTRA_DIST = parallel sem sql niceload parcat env_parallel \ - env_parallel.bash env_parallel.zsh env_parallel.fish env_parallel.ksh \ - env_parallel.pdksh env_parallel.csh env_parallel.tcsh \ - sem.pod parallel.pod env_parallel.pod niceload.pod parallel_tutorial.pod \ - parallel_design.pod parallel_alternatives.pod \ - $(DISTCLEANFILES) +EXTRA_DIST = parallel sem sql niceload parcat env_parallel \ + env_parallel.ash env_parallel.bash env_parallel.csh \ + env_parallel.dash env_parallel.fish env_parallel.ksh \ + env_parallel.pdksh env_parallel.tcsh env_parallel.zsh \ + sem.pod parallel.pod env_parallel.pod niceload.pod \ + parallel_tutorial.pod parallel_design.pod \ + parallel_alternatives.pod $(DISTCLEANFILES) all: all-am diff --git a/src/env_parallel b/src/env_parallel index 041486d4..632a919c 100755 --- a/src/env_parallel +++ b/src/env_parallel @@ -18,28 +18,41 @@ # or write to the Free Software Foundation, Inc., 51 Franklin St, # Fifth Floor, Boston, MA 02110-1301 USA -GREPQ="grep >/dev/null 2>/dev/null" +grepq() { + # grep -q for systems without -q + grep >/dev/null 2>/dev/null "$@" +} + +installer() { + source="$1" + script="$2" + into="$3" + if grepq $script $into; then + true already installed + else + echo $source \`which $script\` >> $into + fi +} while test $# -gt 0; do key="$1" case $key in -i|--install) - eval $GREPQ env_parallel.bash $HOME/.bashrc || - echo '. `which env_parallel.bash`' >> $HOME/.bashrc - eval $GREPQ env_parallel.zsh $HOME/.zshenv || - echo '. `which env_parallel.zsh`' >> $HOME/.zshenv + installer . env_parallel.bash $HOME/.bashrc + installer . env_parallel.zsh $HOME/.zshenv + installer source env_parallel.ksh $HOME/.kshrc + echo $SHELL | grepq /pdksh && + installer . env_parallel.pdksh $HOME/.profile + echo $SHELL | grepq /ash && + installer . env_parallel.ash $HOME/.profile + echo $SHELL | grepq /dash && + installer . env_parallel.dash $HOME/.profile + installer source env_parallel.csh $HOME/.cshrc + installer source env_parallel.tcsh $HOME/.tcshrc mkdir -p $HOME/.config/fish - eval $GREPQ env_parallel.fish $HOME/.config/fish/config.fish || + grepq env_parallel.fish $HOME/.config/fish/config.fish || echo '. (which env_parallel.fish)' >> $HOME/.config/fish/config.fish - eval $GREPQ env_parallel.ksh $HOME/.kshrc || - echo 'source `which env_parallel.ksh`' >> $HOME/.kshrc - eval $GREPQ env_parallel.pdksh $HOME/.profile || - echo '. `which env_parallel.pdksh`' >> $HOME/.profile - eval $GREPQ env_parallel.csh $HOME/.cshrc || - echo 'source `which env_parallel.csh`' >> $HOME/.cshrc - eval $GREPQ env_parallel.tcsh $HOME/.tcshrc || - echo 'source `which env_parallel.tcsh`' >> $HOME/.tcshrc echo 'Installed env_parallel in: ' echo " " $HOME/.bashrc echo " " $HOME/.zshenv @@ -83,6 +96,14 @@ pdksh: Put this in $HOME/.profile: source `which env_parallel.pdksh` E.g. by doing: echo '. `which env_parallel.pdksh`' >> $HOME/.profile Supports: aliases, functions, variables, arrays +ash: Put this in $HOME/.profile: . `which env_parallel.ash` + E.g. by doing: echo '. `which env_parallel.ash`' >> $HOME/.profile + Supports: aliases, variables + +dash: Put this in $HOME/.profile: . `which env_parallel.dash` + E.g. by doing: echo '. `which env_parallel.dash`' >> $HOME/.profile + Supports: aliases, variables + csh: Put this in $HOME/.cshrc: source `which env_parallel.csh` E.g. by doing: echo 'source `which env_parallel.csh`' >> $HOME/.cshrc Supports: aliases, variables, arrays with no special chars diff --git a/src/env_parallel.ash b/src/env_parallel.ash new file mode 100644 index 00000000..f733b0b3 --- /dev/null +++ b/src/env_parallel.ash @@ -0,0 +1,145 @@ +#!/usr/bin/env ash + +# This file must be sourced in ash: +# +# . `which env_parallel.ash` +# +# after which 'env_parallel' works +# +# +# Copyright (C) 2017 +# Ole Tange and Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see +# or write to the Free Software Foundation, Inc., 51 Franklin St, +# Fifth Floor, Boston, MA 02110-1301 USA + +env_parallel() { + # env_parallel.ash + + # Get the --env variables if set + # --env _ should be ignored + # and convert a b c to (a|b|c) + # If --env not set: Match everything (.*) + local _grep_REGEXP="$( + perl -e ' + for(@ARGV){ + /^_$/ and $next_is_env = 0; + $next_is_env and push @envvar, split/,/, $_; + $next_is_env = /^--env$/; + } + $vars = join "|",map { quotemeta $_ } @envvar; + print $vars ? "($vars)" : "(.*)"; + ' -- "$@" + )" + # Deal with --env _ + local _ignore_UNDERSCORE="$( + perl -e ' + for(@ARGV){ + $next_is_env and push @envvar, split/,/, $_; + $next_is_env=/^--env$/; + } + if(grep { /^_$/ } @envvar) { + if(not open(IN, "<", "$ENV{HOME}/.parallel/ignored_vars")) { + print STDERR "parallel: Error: ", + "Run \"parallel --record-env\" in a clean environment first.\n"; + } else { + chomp(@ignored_vars = ); + $vars = join "|",map { quotemeta $_ } "env_parallel", @ignored_vars; + print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; + } + } + ' -- "$@" + )" + + _list_aliases() { + alias | perl -pe 's/=.*//' + } + _body_aliases() { + alias "$@" | perl -pe 's/^/alias /' + } + _list_functions() { + # TODO see http://unix.stackexchange.com/questions/343297/dash-list-declared-functions + true; + } + _list_variables() { + # This may screw up if variables contain \n and = + set | perl -ne 's/=.*// and print;' + } + _body_variables() { + # Crappy typeset -p + for _i in "$@" + do + echo -n "$_i"= + eval echo -n \"\$$_i\" | + perl -pe 's/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\$&/go;'"s/'/\\\'/g; s/[\n]/'\\n'/go;"; + echo + done + } + + # --record-env + if ! perl -e 'exit grep { /^--record-env$/ } @ARGV' -- "$@"; then + (_list_aliases; + _list_functions; + _list_variables) | + cat > $HOME/.parallel/ignored_vars + return 0 + fi + + # Grep alias names + local _alias_NAMES="$(_list_aliases | + grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ )" + local _list_alias_BODIES="_body_aliases $_alias_NAMES" + if [ "$_alias_NAMES" = "" ] ; then + # no aliases selected + _list_alias_BODIES="true" + fi + unset _alias_NAMES + + # Grep function names + local _function_NAMES="$(_list_functions | + grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ )" + local _list_function_BODIES="typeset -f $_function_NAMES" + if [ "$_function_NAMES" = "" ] ; then + # no functions selected + _list_function_BODIES="true" + fi + unset _function_NAMES + + # Grep variable names + local _variable_NAMES="$(_list_variables | + grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ | +# grep -vFf <(readonly -p) | + grep -Ev '^(BASHOPTS|BASHPID|EUID|GROUPS|FUNCNAME|DIRSTACK|_|PIPESTATUS|PPID|SHELLOPTS|UID|USERNAME|BASH_[A-Z_]+)$')" + local _list_variable_VALUES="_body_variables $_variable_NAMES" + if [ "$_variable_NAMES" = "" ] ; then + # no variables selected + _list_variable_VALUES="true" + fi + unset _variable_NAMES + + # Copy shopt (so e.g. extended globbing works) + # But force expand_aliases as aliases otherwise do not work + export PARALLEL_ENV="$( + $_list_alias_BODIES; + $_list_variable_VALUES; + $_list_function_BODIES)"; + unset _list_alias_BODIES + unset _list_variable_VALUES + unset _list_function_BODIES + `which parallel` "$@"; + _parallel_exit_CODE=$? + unset PARALLEL_ENV; + return $_parallel_exit_CODE +} diff --git a/src/env_parallel.dash b/src/env_parallel.dash new file mode 100755 index 00000000..45d944e4 --- /dev/null +++ b/src/env_parallel.dash @@ -0,0 +1,145 @@ +#!/usr/bin/env dash + +# This file must be sourced in dash: +# +# . `which env_parallel.dash` +# +# after which 'env_parallel' works +# +# +# Copyright (C) 2017 +# Ole Tange and Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see +# or write to the Free Software Foundation, Inc., 51 Franklin St, +# Fifth Floor, Boston, MA 02110-1301 USA + +env_parallel() { + # env_parallel.dash + + # Get the --env variables if set + # --env _ should be ignored + # and convert a b c to (a|b|c) + # If --env not set: Match everything (.*) + local _grep_REGEXP="$( + perl -e ' + for(@ARGV){ + /^_$/ and $next_is_env = 0; + $next_is_env and push @envvar, split/,/, $_; + $next_is_env = /^--env$/; + } + $vars = join "|",map { quotemeta $_ } @envvar; + print $vars ? "($vars)" : "(.*)"; + ' -- "$@" + )" + # Deal with --env _ + local _ignore_UNDERSCORE="$( + perl -e ' + for(@ARGV){ + $next_is_env and push @envvar, split/,/, $_; + $next_is_env=/^--env$/; + } + if(grep { /^_$/ } @envvar) { + if(not open(IN, "<", "$ENV{HOME}/.parallel/ignored_vars")) { + print STDERR "parallel: Error: ", + "Run \"parallel --record-env\" in a clean environment first.\n"; + } else { + chomp(@ignored_vars = ); + $vars = join "|",map { quotemeta $_ } "env_parallel", @ignored_vars; + print $vars ? "($vars)" : "(,,nO,,VaRs,,)"; + } + } + ' -- "$@" + )" + + _list_aliases() { + alias | perl -pe 's/=.*//' + } + _body_aliases() { + alias "$@" | perl -pe 's/^/alias /' + } + _list_functions() { + # TODO see http://unix.stackexchange.com/questions/343297/dash-list-declared-functions + true; + } + _list_variables() { + # This may screw up if variables contain \n and = + set | perl -ne 's/=.*// and print;' + } + _body_variables() { + # Crappy typeset -p + for _i in "$@" + do + echo -n "$_i"= + eval echo -n \"\$$_i\" | + perl -pe 's/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\$&/go;'"s/'/\\\'/g; s/[\n]/'\\n'/go;"; + echo + done + } + + # --record-env + if ! perl -e 'exit grep { /^--record-env$/ } @ARGV' -- "$@"; then + (_list_aliases; + _list_functions; + _list_variables) | + cat > $HOME/.parallel/ignored_vars + return 0 + fi + + # Grep alias names + local _alias_NAMES="$(_list_aliases | + grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ )" + local _list_alias_BODIES="_body_aliases $_alias_NAMES" + if [ "$_alias_NAMES" = "" ] ; then + # no aliases selected + _list_alias_BODIES="true" + fi + unset _alias_NAMES + + # Grep function names + local _function_NAMES="$(_list_functions | + grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ )" + local _list_function_BODIES="typeset -f $_function_NAMES" + if [ "$_function_NAMES" = "" ] ; then + # no functions selected + _list_function_BODIES="true" + fi + unset _function_NAMES + + # Grep variable names + local _variable_NAMES="$(_list_variables | + grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ | +# grep -vFf <(readonly -p) | + grep -Ev '^(BASHOPTS|BASHPID|EUID|GROUPS|FUNCNAME|DIRSTACK|_|PIPESTATUS|PPID|SHELLOPTS|UID|USERNAME|BASH_[A-Z_]+)$')" + local _list_variable_VALUES="_body_variables $_variable_NAMES" + if [ "$_variable_NAMES" = "" ] ; then + # no variables selected + _list_variable_VALUES="true" + fi + unset _variable_NAMES + + # Copy shopt (so e.g. extended globbing works) + # But force expand_aliases as aliases otherwise do not work + export PARALLEL_ENV="$( + $_list_alias_BODIES; + $_list_variable_VALUES; + $_list_function_BODIES)"; + unset _list_alias_BODIES + unset _list_variable_VALUES + unset _list_function_BODIES + `which parallel` "$@"; + _parallel_exit_CODE=$? + unset PARALLEL_ENV; + return $_parallel_exit_CODE +} diff --git a/src/env_parallel.pod b/src/env_parallel.pod index 21a52694..32cb67e6 100644 --- a/src/env_parallel.pod +++ b/src/env_parallel.pod @@ -81,6 +81,50 @@ Same as GNU B. =head1 SUPPORTED SHELLS +=head2 Ash + +B<--env> is supported to export only the variable, or alias with the +given name. Multiple B<--env>s can be given. + +Installation + +Put this in $HOME/.profile: + + . `which env_parallel.ash` + +E.g. by doing: + + echo '. `which env_parallel.ash`' >> $HOME/.profile + +=over 8 + +=item aliases + + alias myecho='echo aliases' + env_parallel myecho ::: work + env_parallel -S server myecho ::: work + env_parallel --env myecho myecho ::: work + env_parallel --env myecho -S server myecho ::: work + +=item functions + +Functions cannot be used. If you find a way to list function names +and definitions please contact B. + +=item variables + + myvar=variables + env_parallel echo '$myvar' ::: work + env_parallel -S server echo '$myvar' ::: work + env_parallel --env myvar echo '$myvar' ::: work + env_parallel --env myvar -S server echo '$myvar' ::: work + +=item arrays + +Arrays are not supported by Ash. + +=back + =head2 Bash B<--env> is supported to export only the variable, alias, function, or @@ -184,6 +228,51 @@ Not supported by B. =back +=head2 Dash + +B<--env> is supported to export only the variable, or alias with the +given name. Multiple B<--env>s can be given. + +Installation + +Put this in $HOME/.profile: + + . `which env_parallel.dash` + +E.g. by doing: + + echo '. `which env_parallel.dash`' >> $HOME/.profile + +=over 8 + +=item aliases + + alias myecho='echo aliases' + env_parallel myecho ::: work + env_parallel -S server myecho ::: work + env_parallel --env myecho myecho ::: work + env_parallel --env myecho -S server myecho ::: work + +=item functions + +Functions cannot be used. If you find a way to list function names +and definitions please contact B. + +=item variables + + myvar=variables + env_parallel echo '$myvar' ::: work + env_parallel -S server echo '$myvar' ::: work + env_parallel --env myvar echo '$myvar' ::: work + env_parallel --env myvar -S server echo '$myvar' ::: work + +=item arrays + +Arrays are not supported by Dash. + +=back + + =head2 fish B<--env> is supported to export only the variable, alias, function, or diff --git a/src/niceload b/src/niceload index 30e2735e..294612a6 100755 --- a/src/niceload +++ b/src/niceload @@ -24,7 +24,7 @@ use strict; use Getopt::Long; $Global::progname="niceload"; -$Global::version = 20170123; +$Global::version = 20170206; Getopt::Long::Configure("bundling","require_order"); get_options_from_array(\@ARGV) || die_usage(); if($opt::version) { diff --git a/src/parallel b/src/parallel index a493e8c0..d146a259 100755 --- a/src/parallel +++ b/src/parallel @@ -1361,7 +1361,7 @@ sub check_invalid_option_combinations { sub init_globals { # Defaults: - $Global::version = 20170202; + $Global::version = 20170208; $Global::progname = 'parallel'; $Global::infinity = 2**31; $Global::debug = 0; diff --git a/src/parallel.pod b/src/parallel.pod index 8753b2a4..6c9dd6d5 100644 --- a/src/parallel.pod +++ b/src/parallel.pod @@ -2180,6 +2180,11 @@ fill: seq 1000 | parallel --pipe --tee --tag 'grep {1} | wc {2}' ::: {0..9} ::: -l -c +How many words contain a..z and how many bytes do they fill? + + parallel -a /usr/share/dict/words --pipepart --tee --tag \ + 'grep {1} | wc {2}' ::: {a..z} ::: -l -c + =item B<--termseq> I diff --git a/src/sql b/src/sql index 26e18534..473809f2 100755 --- a/src/sql +++ b/src/sql @@ -576,7 +576,7 @@ $Global::Initfile && unlink $Global::Initfile; exit ($err); sub parse_options { - $Global::version = 20170123; + $Global::version = 20170206; $Global::progname = 'sql'; # This must be done first as this may exec myself diff --git a/testsuite/REQUIREMENTS b/testsuite/REQUIREMENTS index 9b7c99c8..fe7d87bb 100644 --- a/testsuite/REQUIREMENTS +++ b/testsuite/REQUIREMENTS @@ -35,12 +35,12 @@ sql mysql://root:"$mysqlrootpass"@/mysql "DROP DATABASE `whoami`;DROP USER '`who sql mysql://root:"$mysqlrootpass"@/mysql "CREATE DATABASE `whoami`;CREATE USER '`whoami`'@'localhost' IDENTIFIED BY '`whoami`'; GRANT ALL ON `whoami`.* TO '`whoami`'@'localhost';" # SHELLS -$INSTALL ash csh fdclone fish fizsh ksh mksh pdksh posh rc rush sash tcsh yash zsh +$INSTALL ash csh dash fdclone fish fizsh ksh mksh pdksh posh rc rush sash tcsh yash zsh SSHPASS=`goodpasswd` export SSHPASS #shells="bash sh csh ash tcsh zsh ksh fish fizsh mksh pdksh posh rc sash yash nopathbash nopathcsh" -shells="bash sh csh ash tcsh zsh ksh fish fizsh mksh posh rc sash yash nopathbash nopathcsh" +shells="bash sh csh ash dash tcsh zsh ksh fish fizsh mksh posh rc sash yash nopathbash nopathcsh" create_shell_user() { shell="$1" sudo deluser $shell && sudo mv /home/$shell /tmp/$shell.$RANDOM