Skip to content
Advertisement

Why does posh fail to perform pathname expansion when a part of the path is specified within double-quotes?

Consider the following simple shell script:

JavaScript

I get the expected output with bash, ksh, zsh and dash, but I don’t get it with posh:

JavaScript

I am trying to understand if the behaviour of posh is correct as per the POSIX standard or if it is a bug.

The relevant section in the POSIX documents seem to be “2.6 Word Expansion”:

Both of them mention that pathname expansion occurs before quote removal.

  1. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.
  2. Quote removal (see Quote Removal) shall always be performed last.

Considering this, the posh behaviour looks right because "bar"/* does not literally match any path above before the quote removal, so path expansion does not occur.

So this led me to suspect that if there were a directory literally named "bar", i.e. the quotes were part of the directory name, then posh would have matched it. But the following altered script shows that this is not true.

JavaScript

Here is the output:

JavaScript

So the pattern "bar"/* in posh matches neither the path bar/baz nor the path "bar"/baz. What does it match then? Is the posh behaviour a bug or a feature?

Here are the version details in case it helps you to helps me:

JavaScript

Advertisement

Answer

This is a bug in posh — see bug #636601. It is still open as of posh version 0.12.6.

Attached to the discussion of that bug you’ll find a patch. When applying that, posh behaves similar to bash (so in your first example echo "bar"/* gives bar/baz).

Furthermore, that behaviour of bash (and patched posh) does conform to POSIX. The standard says

  1. Quote removal (see Quote Removal) shall always be performed last.

This is meant literally, as a purely syntactical action to remove protective quotes in the very last step. The semantical meaning of quotes will still apply in earlier steps, as pointed out by hek2mgl. (Otherwise, e.g. a quotation like "*" would not have any effect at all.)

So on second thought, this conclusion is not correct:

Considering this, the posh behaviour looks right because “bar”/* does not literally match any path above before the quote removal, so path expansion does not occur.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement