<div dir="ltr">On Wed, May 1, 2013 at 12:20 PM, Elias Pipping <span dir="ltr"><<a href="mailto:pipping.elias@gmail.com" target="_blank">pipping.elias@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div>I'd like to talk about bash for a minute(*).<br>

<div><br></div><div>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.</div>


</div><div><br></div><div>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).<br>


</div><div><br></div><div><div>(*) The minute is a lie.</div><div>(**) I could not find anything on the topic on <a href="http://dune-project.org" target="_blank">dune-project.org</a> but maybe I did not look hard enough.<br>


</div><div><br></div></div><div><br></div><div>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.<br>


</div><div><br></div><div>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).<br>


</div><div><br></div><div>Here's a quick run-down of some features of interest:</div><div><br></div><div>  posix shell: $(cmd) to capture output of a command</div><div>  2.02 (e): [[ command (a replacement for `test` or `[`)</div>


<div>  2.05b (n): <<< "here-string" operator<br></div><div><div>  2.05b (g): [:word:] character classes<br></div><div>  4.0 (hh): ${var,}, ${var,,}, ${var^}, ${var^^}, etc.</div></div></div></blockquote>

<div><br></div><div style>Maybe I should also mention 2.0 (q): ${!var}, which is the same as eval \${$var}.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><div><div>
</div><div>(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).</div><div><br></div>
<div>Here are some scenarios.</div><div><br></div><div>(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</div><div>
<br></div><div>(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:<br></div></div><div><div><br></div><div>test:</div>
<div><div><div>  bin/dunecontrol:10:if test -z $MAKE; then</div><div>  bin/duneproject:187:  while [ -z $PROJECT ]; do</div><div>  bin/duneproject:218:  while [ -z $VERSION ]; do</div><div>  bin/duneproject:221:  while [ -z $MAINTAINER ]; do</div>


<div>  lib/dunemodules.lib:16:if test -z $GREP; then</div><div>  lib/dunemodules.lib:167:  if test -z $DUNE_CONTROL_PATH; then</div></div><div><br></div><div>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</div>

</div></div></div></blockquote><div><br></div><div style>Correction: they're not actually synonyms. `test` and [ continue to be annoying.</div><div style><br></div><div style><div>  $ a="x y"</div><div>  $ [ -z $a ]</div>

<div>  bash: [: x: binary operator expected</div><div>  $ test -z $a<br></div><div>  bash: test: x: binary operator expected</div><div><br></div><div style>What is true, however, is that [[ has no such problems. [[ -z $a ]] just works.</div>

<div style><br></div><div style>Consequently, the above code needs to be fixed either way.</div></div><div style> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><div><div><div> and [[ handles quoting properly; In particular, we do not need to write</div>
<div><br></div><div>  test "x" = "x$var"</div><div><br></div><div>anymore; a plain [[ -z $var ]] will do.</div><div><br></div><div>(3) If we rely at least on bash 2.05b (from '02), this code can stay, too:</div>


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


<div>  lib/dunemodules.lib:625:        local lowercase=`tr 'A-Z' 'a-z' <<< $1`</div><div>  lib/dunemodules.lib:626:        local uppercase=`tr 'a-z' 'A-Z' <<< $1`</div></div>


<div><br></div><div>character classes:</div><div>  lib/dunemodules.lib:447:  echo ${@//[[:punct:]]/_}</div><div><br></div><div>( Rant: Rather than [[:punct:]] one could just use [:punct:] here; the double brackets only serve to join multiple character classes, as in [[:space:][:punct:]]. )</div>


</div><div><br></div><div>If this hasn't been decided yet, my recommendation would be to rely on bash 2.05b and thus a shell from 2002.<span class=""><font color="#888888"><br></font></span></div><span class=""><font color="#888888"><div>

<br></div><div><br></div><div>Elias</div></font></span></div></div>
</div>
</blockquote></div><br></div></div>