Shell – POSIX shell: does `$` lose its special meaning if it is the last character in a word

posixshell

On ash, dash and bash, when I run

$ echo ab$

it returns

ab$

Is this behavior specified by POSIX or is it just a common convention in POSIX-compliant shells? I couldn't find anything on the POSIX Shell Command Language page that mentions this behavior.

Best Answer

$ does not have a special meaning by itself (try echo $), only when combined with other character after it and forming an expansion, e.g. $var (or ${var}), $(util), $((1+2)).

The $ gets its "special" meaning as defining an expansion in the POSIX standard under the section Token Recognition:

If the current character is an unquoted $ or `, the shell shall identify the start of any candidates for parameter expansion, command substitution, or arithmetic expansion from their introductory unquoted character sequences: $ or ${, $( or `, and $((, respectively. The shell shall read sufficient input to determine the end of the unit to be expanded (as explained in the cited sections). While processing the characters, if instances of expansions or quoting are found nested within the substitution, the shell shall recursively process them in the manner specified for the construct that is found. The characters found from the beginning of the substitution to its end, allowing for any recursion necessary to recognize embedded constructs, shall be included unmodified in the result token, including any embedded or enclosing substitution operators or quotes. The token shall not be delimited by the end of the substitution.

So, if $ does not form an expansion, other parsing rules come into effect:

If the previous character was part of a word, the current character shall be appended to that word.

That covers your ab$ string.

In the case of a lone $ (the "new word" would be the $ by itself):

The current character is used as the start of a new word.

The meaning of the generated word containing a $ that is not a standard expansion is explicitly defined as unspecified by POSIX.

Also note that $ is the last character in $$, but that this also happens to be the variable that holds the current shell's PID. In bash, !$ may invoke a history expansion (the last argument af the previous command). So in general, no, $ is not without meaning at the end of an unquoted word, but at the end of a word it does at least not denote a standard expansion.