[Dune-devel] bash in shell scripts

Elias Pipping pipping.elias at gmail.com
Wed May 1 12:20:44 CEST 2013


Hello,

I'd like to talk about bash for a minute(*).

There are quite a couple of shell scripts in dune-common, some with the
shebang-line /bin/bash and others with /bin/sh. Rumor has it(**), recent
bash features should not be used. Judging by some of the code, no bash
features at all should be used, judging by other code, some can be.

I'd like some clarity: what version of bash can be relied upon and where (I
take it scripts that are only supposed to be run by developers have
different requirements than, say, dunecontrol).

(*) The minute is a lie.
(**) I could not find anything on the topic on dune-project.org but maybe I
did not look hard enough.


Even if it is decided (or already has been) that e.g. Version 2.05b of bash
can be relied upon, hardly anyone will know what the implications are. Let
me elaborate on that for a bit.

When a bash feature has been introduced can be answered by a look at the
NEWS file of bash. For each version, there's a list of new features, each
with an associated letter, so that one can refer to them by a handle like
3.2 (b).

Here's a quick run-down of some features of interest:

  posix shell: $(cmd) to capture output of a command
  2.02 (e): [[ command (a replacement for `test` or `[`)
  2.05b (n): <<< "here-string" operator
  2.05b (g): [:word:] character classes
  4.0 (hh): ${var,}, ${var,,}, ${var^}, ${var^^}, etc.

(I did not mention regular expressions here, since their history in bash is
a bit messy and one only really wants to use them with bash 4 even though
they were introduced earlier).

Here are some scenarios.

(1) If we at least rely on posix shell, we can still use $(cmd), which is
currently mixed with `cmd`. It behaves a lot nicer w.r.t. e.g .nesting

(2) If we rely at least on version 2.02 of bash (from '98 afaict), we can
use [[ in place of test or [. We already implicitly do:

test:
  bin/dunecontrol:10:if test -z $MAKE; then
  bin/duneproject:187:  while [ -z $PROJECT ]; do
  bin/duneproject:218:  while [ -z $VERSION ]; do
  bin/duneproject:221:  while [ -z $MAINTAINER ]; do
  lib/dunemodules.lib:16:if test -z $GREP; then
  lib/dunemodules.lib:167:  if test -z $DUNE_CONTROL_PATH; then

Since the arguments are not quoted here, if it expands to nothing, old
shells will choke on this and signal a syntax error. In bash, test, [, and
[[ are just synonyms and [[ handles quoting properly; In particular, we do
not need to write

  test "x" = "x$var"

anymore; a plain [[ -z $var ]] will do.

(3) If we rely at least on bash 2.05b (from '02), this code can stay, too:

here-string:
  lib/dunemodules.lib:589:        local lowercase=`tr 'A-Z' 'a-z' <<< $1`
  lib/dunemodules.lib:590:        local uppercase=`tr 'a-z' 'A-Z' <<< $1`
  lib/dunemodules.lib:625:        local lowercase=`tr 'A-Z' 'a-z' <<< $1`
  lib/dunemodules.lib:626:        local uppercase=`tr 'a-z' 'A-Z' <<< $1`

character classes:
  lib/dunemodules.lib:447:  echo ${@//[[:punct:]]/_}

( Rant: Rather than [[:punct:]] one could just use [:punct:] here; the
double brackets only serve to join multiple character classes, as in
[[:space:][:punct:]]. )

If this hasn't been decided yet, my recommendation would be to rely on bash
2.05b and thus a shell from 2002.


Elias
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.dune-project.org/pipermail/dune-devel/attachments/20130501/e5501af8/attachment.htm>


More information about the Dune-devel mailing list