Subject: bug#32703: echo_man_error

From: Pádraig Brady <[email-masked]>
Date: Sat, 27 Oct 2018 04:55:28 -0700

On 24/09/18 21:51, Pádraig Brady wrote:
> On 24/09/18 15:15, Eric Blake wrote:
>> On 9/23/18 9:48 PM, Pádraig Brady wrote:
>>
>>> +++ b/NEWS
>>> @@ -5,6 +5,12 @@ GNU coreutils NEWS                                    -*- outline -*-
>>>   ** Bug fixes
>>>   
>>>     df no longer corrupts displayed multibyte characters on macOS.
>>> +  [bug introduced with coreutils-8.18]
>>> +
>>> +** Changes in behavior
>>> +
>>> +  echo now always processes backslash escapes when the POSIXLY_CORRECT
>>> +  environment variable is set.
>>
>> Having re-read the POSIX wording, I'm not quite sure we are still accurate.
>>
>>> +++ b/src/echo.c
>>> @@ -108,8 +108,9 @@ int
>>>   main (int argc, char **argv)
>>>   {
>>>     bool display_return = true;
>>> +  bool posixly_correct = getenv ("POSIXLY_CORRECT");
>>>     bool allow_options =
>>> -    (! getenv ("POSIXLY_CORRECT")
>>> +    (! posixly_correct
>>>        || (! DEFAULT_ECHO_TO_XPG && 1 < argc && STREQ (argv[1], "-n")));
>>
>> This special-cases a literal "-n" as the first argument, while POSIX 
>> states (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html)
>>
>> Implementations shall not support any options.
>>
>> A string to be written to standard output. If the first operand is -n, 
>> or if any of the operands contain a <backslash> character, the results 
>> are implementation-defined.
>>
>> and then with XSI shading states:
>>
>> On XSI-conformant systems, if the first operand is -n, it shall be 
>> treated as a string, not an option.
>>
>> So my initial patch (which you took and improved) still isn't quite right.
> 
> I noticed that POSIX wording too,
> but erred on the side of consistency:
> 
>   $ bash -c 'set -o posix; shopt -s xpg_echo; echo -n foo'
>   -n foo
> 
>   $ bash -c 'set -o posix; echo -n foo'
>   foo
>   $ dash -c 'echo -n foo'
>   foo
> 
> Now we do have compile time control over xpg mode so
> should probably restrict the no option processing
> to that mode?
> In summary the handling of -n specially is weird
> and inconsistent with bash, so in a separate patch
> I propose we handle all (leading) options also
> with POSIXLY_CORRECT to be consistent with bash.
> 
> Oh hang on. It's the "xpg_echo" bash setting that enables -e by default :/
> We don't have a runtime setting for that at present.
> 
> $ bash -c 'set -o posix; echo -ne a\\nb\\n'
> a
> b
> bash -c 'set -o posix; echo -E a\\nb'
> a\nb
> 
> $ bash -c 'set -o posix; shopt -s xpg_echo; echo a\\nb'
> a
> b
> $ bash -c 'set -o posix; echo a\\nb'
> a\nb
> $ bash -c 'set -o posix; echo -e a\\nb'
> a
> b
> 
> So there is no way to be consistent with bash and dash I think.
> Let's have bash and coreutils consistent at least.
> The only question is whether POSIXLY_CORRECT in coreutils
> is equiv to `shopt -s xpg_echo` in bash or not.
> Assuming it is, then we'll need to echo -n when set as you say.
> 
> Le sigh. What a mess

Thinking a bit more about this,

basically for -e, in echo(1), bash, and dash,
where -e is not interpreted as an option
we should interpret backslashes by default.
That's what this patch now does.

For -n, dash and bash (set -o posix), do give the
facility to outputting without the trailing newline
by interpreting the -n option, and POSIX says this
is implementation defined, so let's continue to
provide this facility.

We've compile time support for the less
frequently needed facility to output a leading -n,
dash doesn't currently have this facility.
bash supports this with `shopt -s xpg_echo`.
I suggest we don't change this with POSIXLY_CORRECT,
or if we do with a subsequent patch, to do
do it with a separate env var/value.

Pushing these two patches now...

cheers,
Pádraig