Andre Majorel wrote:
> On 2016-12-16, Janis Papanagnou <
janis_pa...@hotmail.com> wrote:
>> On 16.12.2016 14:03, Janis Papanagnou wrote:
>>> On 16.12.2016 13:26, Andre Majorel wrote:
>>>> […]
>>>> I thought that
>>>>
>>>> cmd ${var+-x "$var"}
>>>>
>>>> would do the trick. Turns out that with most shells, it doesn't
>>>> if $var is set but empty.
>>>>
>>>> - Dash 0.5.7 expands « ${var+something "$var"} » to two words
>>>> containing "something" and the value of $var respectively,
>>>> which is what I wanted.
>>>>
>>>> - Ksh 93u+ omits the second word if $var is empty.
>>>
>>> Just to be sure; you say that ksh omits the second = _empty_ word?
>
> Yes.
>
> […]
>>> But in case of
>>>
>>> cmd ${var+-x "$var"}
>>>
>>> the final space is removed before it's passed to cmd,
Which “final space” are you referring to?
>>> since the expression is unquoted. To me this looks pretty much like
>>> standard behaviour.
>
> Does that means that Dash's behaviour is non-standard, then ?
According to POSIX.1-2008 chapter “2. Shell Command Language”, section
“2.6.2 Parameter Expansion” [1],
${parameter+word}
shall be substituted with “word” if “parameter” is “Set But Null” (whereas
the standard uses “null” and “Null” to mean the string of length zero,
presumably because then the NUL character would be the value in C).
AIUI this means that
${var+something "$var"}
shall be substituted with
something "$var"
if “var” is “Set But Null”.
The standard also says:
| If a parameter expansion occurs inside double-quotes:
|
| * Pathname expansion shall not be performed on the results of the
| expansion.
|
| * Field splitting shall not be performed on the results of the
| expansion.
From which we can assume that if parameter expansion does _not_ occur inside
double-quotes (so without quotes, as single-quotes would prevent expansion
altogether), both pathname expansion and field splitting shall be performed.
This is also substantiated by
| 2.6.5 Field Splitting
|
| After parameter expansion (Parameter Expansion), […] the shell shall scan
| the results of expansions and substitutions that did not occur in double-
| quotes for field splitting and multiple fields can result.
|
| The shell shall treat each character of the IFS as a delimiter and use the
| delimiters as field terminators to split the results of parameter
| expansion, command substitution, and arithmetic expansion into fields.
There are no pathnames, and field splitting with the default $IFS value
would leave
'something' "$var"
Since “$var” is syntactically a parameter reference, and parameter expansion
is _not_ one of the forms of expansion that “shall not be performed on the
results of the expansion” if it “occurs inside double-quotes”, the shell
then shall perform parameter expansion again, substituting the above with
'something' ""
because “If the parameter is not enclosed in braces, and is a name, the
expansion shall use the longest valid name (see XBD Name), whether or not
the variable represented by that name exists” and “The value, if any, of
‘parameter’ shall be substituted”, the empty string shall be substituted.
So ISTM that there should be two words according to the standard, one non-
empty and one empty, and as dash is doing that – test code:
(x=''; printf '"%s"\n' ${x+-x "$x"})
–, it is standards-compliant there while the shells that do not are not.
[1]
<
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02>