I was burned by dash's local V=' x' semantics, in spite of having
reported and studied this wart, at length, a few years ago. This arose
again when Assaf discovered one of grep's test programs would
malfunction on dash-based shells, e.g., on most Debian systems:
https://bugs.gnu.org/24116#11

I don't want to have to debug or think about this again -- at least
not in the free-software test scripts that I tend -- so propose to
make init.sh's initial shell-triage stage (where it tries to find a
useful shell, i.e., one that supports '$(...)', local and a few other
features) reject any shell like dash with this unfortunate and subtly
misleading attribute.

While currently dash cannot be said to be nonconforming, this
interpretation (thanks, Eric) suggests that the behavior of bash and
zsh is what will be standardized, so dash should change sooner rather
than later:

http://austingroupbugs.net/view.php?id=351

In the mean time, I feel more than justified in making our tests avoid dash.

If no one objects, I'll push this in a couple of days.
From ac32368bf8a5e0d58c608bc358655ba908add6a7 Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email protected]>
Date: Mon, 1 Aug 2016 09:37:15 -0700
Subject: [PATCH] tests/init.sh: exclude dash with bad "local" semantics

* tests/init.sh (gl_shell_test_script_): Add a function to
eliminate a shell like "dash" (unlike bash, zsh) that has
surprising/risky "local var='...'" semantics.  Inspired by
the problem and discussion in https://bugs.gnu.org/24116#11.
---
 ChangeLog     | 8 ++++++++
 tests/init.sh | 8 ++++++++
 2 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 7cfc6f7..3bf4410 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2016-08-06  Jim Meyering  <[email protected]>
+
+       tests/init.sh: exclude dash with bad "local" semantics
+       * tests/init.sh (gl_shell_test_script_): Add a function to
+       eliminate a shell like "dash" (unlike bash, zsh) that has
+       surprising/risky "local var='...'" semantics.  Inspired by
+       the problem and discussion in https://bugs.gnu.org/24116#11.
+
 2016-08-02  Ján Tomko  <[email protected]>

        maint.mk: expand the prohibit_doubled_word regex
diff --git a/tests/init.sh b/tests/init.sh
index 97e4e4b..09b0739 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -128,6 +128,13 @@ else
 fi

 # We require $(...) support unconditionally.
+# We require non-surprising "local" semantics (this eliminates dash).
+# This takes the admittedly draconian step of eliminating dash, because the
+# assignment tab=$(printf '\t') works fine, yet preceding it with "local "
+# transforms it into an assignment that sets the variable to the empty string.
+# That is too counter-intuitive, and can lead to subtle run-time malfunction.
+# The example below is less subtle in that with dash, it evokes the run-time
+# exception "dash: 1: local: 1: bad variable name".
 # We require a few additional shell features only when $EXEEXT is nonempty,
 # in order to support automatic $EXEEXT emulation:
 # - hyphen-containing alias names
@@ -151,6 +158,7 @@ fi
 gl_shell_test_script_='
 test $(echo y) = y || exit 1
 f_local_() { local v=1; }; f_local_ || exit 1
+f_dash_local_fail_() { local t=$(printf " 1"); }; f_dash_local_fail_
 score_=10
 if test "$VERBOSE" = yes; then
   test -n "$( (exec 3>&1; set -x; P=1 true 2>&3) 2> /dev/null)" && score_=9
-- 
2.8.0-rc2

Reply via email to