[Toybox] And again.

Rob Landley rob at landley.net
Thu Aug 27 23:28:09 PDT 2020


I'm trying hard not to bother you anymore, but I think the bash man page is
wrong. It says says:

       case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
              A case command first expands word, and tries to match it against
              each pattern in turn, using the same matching rules as for path‐
              name  expansion  (see  Pathname  Expansion  below).  The word is
              expanded using tilde expansion, parameter  and  variable  expan‐
              sion,  arithmetic  expansion, command substitution, process sub‐
              stitution and quote removal.  Each pattern examined is  expanded
              using  tilde expansion, parameter and variable expansion, arith‐
              metic expansion, command substitution, and process substitution.

And I have questions:

1) Bash DOES remove quotes from the pattern, it has to because splitting is
disabled so spaces and $IFS can get inserted:

  $ x() { case "$@" in "a b") echo hello; esac;}; x a b
  hello
  $ IFS=z; x() { case "$@" in "a b") echo hello; esac;}; x a b
  hello
  $ IFS=z; x() { case "$*" in "a b") echo hello; esac;}; x a b
  $ IFS=z; x() { case "$*" in "azb") echo hello; esac;}; x a b
  hello

(If you correct it could you just have one list of expansions so we don't have
to compare two lists carefully to see how they differ?)

2) process substitution? Really? Under what circumstances does:

  case <(potato) in $PATTERN) echo hello;; esac

trigger usefully? Given that $PATTERN is going to be checking /dev/fd/63 and not
reading FROM it? I don't see a variable that "word" gets saved into so the body
couldn't even USE the resulting filename unless you did something clever with
${blah:=<(potato)} in the "word" maybe? Has anyone ever actually _used_ this?

My code is treating <() as a form of redirection, so it's handled by
expand_redir() rather than expand_arg_nobrace(), and moving it is problematic
because only one context has the filehandle tracking (I.E. recording what to
close again afterwards). I'm supporting nommu so can't do this after fork()...

3) $(case a in a); echo hello; esac) is not something my parsing can handle (it
just counts quotes and parentheses, it's not parsing flow control statements
inside what is essentially a nested quoting context), and I would have to rip
out SO much stuff to make it do so I think I'm ok with not supporting that for
the moment. And technically you can do $(case a in (a); echo hello; esac) and
that does work.

(This is the "wait for somebody to complain" mode where if somebody comes to me
with an existing script my code can't handle, I have to care, but until then...)

Anyway, 2 and 3 I can document as deviations from the bash man page, but 1 is
the bash man page deviating from what bash does.

Rob


More information about the Toybox mailing list