help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: any plans for command substitution that preserves trailing newlines?


From: Christoph Anton Mitterer
Subject: Re: any plans for command substitution that preserves trailing newlines?
Date: Tue, 01 Jun 2021 23:03:33 +0200
User-agent: Evolution 3.38.3-1

On Tue, 2021-06-01 at 09:28 -0400, Chet Ramey wrote:
> On 5/31/21 9:34 PM, Christoph Anton Mitterer wrote:
> 
> > Can someone (Chet?) confirm that the solution with adding *any*
> > character and removing it later on works (i.e. with any locale and
> > any
> > valid variable content, which is, AFAIU, anything but NUL)?
> 
> If you want to append a byte and then be sure you can remove that
> byte
> later, make sure to set the locale to "C" before removing it.

So basically:
-------------------------------------
LC_ALL=<whatever>

subst="$( command; rc=$?; printf 'x'; exit $rc )"

#remember rc if necessary
rc=$?

#remove the sentinel
LC_ALL=C subst="${subst%x}"
-------------------------------------
is guaranteed to work for every locale and every sentinel value (not
just 'x')... and should also be portable, right?


And:
For UTF-8, the same work even when not setting LC_ALL=C at the removal,
right?


What I coudln't find out was:
Does:
  LC_ALL=C subst="${subst%x}"
work as I'd expect, that is LC_ALL being active *ony* for the
assignment and parameter expansion?


I've read in POSIX' "2.9.1 Simple Commands":
   Variable assignments shall be performed as follows:
   
       If no command name results, variable assignments shall affect the
   current execution environment.
   
       If the command name is not a special built-in utility or function,
   the variable assignments shall be exported for the execution
   environment of the command and shall not affect the current execution
   environment except as a side-effect of the expansions performed in step
   4. In this case it is unspecified:
   
           Whether or not the assignments are visible for subsequent
   expansions in step 4
   
           Whether variable assignments made as side-effects of these
   expansions are visible for subsequent expansions in step 4, or in the
   current shell execution environment, or both
   
       If the command name is a standard utility implemented as a function
   (see XBD Utility), the effect of variable assignments shall be as if
   the utility was not implemented as a function.
   
       If the command name is a special built-in utility, variable
   assignments shall affect the current execution environment. Unless the
   set -a option is on (see set), it is unspecified:
   
           Whether or not the variables gain the export attribute during
   the execution of the special built-in utility
   
           Whether or not export attributes gained as a result of the
   variable assignments persist after the completion of the special built-
   in utility
   
       If the command name is a function that is not a standard utility
   implemented as a function, variable assignments shall affect the
   current execution environment during the execution of the function. It
   is unspecified:
   
           Whether or not the variable assignments persist after the
   completion of the function
   
           Whether or not the variables gain the export attribute during
   the execution of the function
   
           Whether or not export attributes gained as a result of the
   variable assignments persist after the completion of the function (if
   variable assignments persist after the completion of the function)


But the assignment subst= is neither a command nor special built in or
so.
The closest is probably:
>If no command name results, variable assignments shall affect the
>current execution environment.

But when I tried it out, the environment wasn't affected, i.e.
1) Before:
$ locale
LANG=en_DE.UTF-8
LANGUAGE=
LC_CTYPE="en_DE.UTF-8"
LC_NUMERIC="en_DE.UTF-8"
LC_TIME="en_DE.UTF-8"
LC_COLLATE="en_DE.UTF-8"
LC_MONETARY="en_DE.UTF-8"
LC_MESSAGES="en_DE.UTF-8"
LC_PAPER="en_DE.UTF-8"
LC_NAME="en_DE.UTF-8"
LC_ADDRESS="en_DE.UTF-8"
LC_TELEPHONE="en_DE.UTF-8"
LC_MEASUREMENT="en_DE.UTF-8"
LC_IDENTIFICATION="en_DE.UTF-8"
LC_ALL=

2) Removal:
$ LC_ALL=C c=${b%$s}

3) After:
$ locale
LANG=en_DE.UTF-8
LANGUAGE=
LC_CTYPE="en_DE.UTF-8"
LC_NUMERIC="en_DE.UTF-8"
LC_TIME="en_DE.UTF-8"
LC_COLLATE="en_DE.UTF-8"
LC_MONETARY="en_DE.UTF-8"
LC_MESSAGES="en_DE.UTF-8"
LC_PAPER="en_DE.UTF-8"
LC_NAME="en_DE.UTF-8"
LC_ADDRESS="en_DE.UTF-8"
LC_TELEPHONE="en_DE.UTF-8"
LC_MEASUREMENT="en_DE.UTF-8"
LC_IDENTIFICATION="en_DE.UTF-8"
LC_ALL=



Thanks for your help guys :-)


Cheers,
Chris.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]