Re: leaks fd for internal functions but not external command

2019-07-24 Thread Sam Liddicott
Thanks for that thoughtful response.

* I understand that the design decision is to have variable file
descriptors to stay open after per-command redirection
* I understand that implementation constraints make it impossible to do
this uniformly (for external command redirection)
* I understand that it is difficult for the script author to detect which
case his code will be

I'm trying to make bash better and more usable.

The shell normally does a great job of hiding the difference between
internal and external commands, so even though it's very well documented,
most of the time the user doesn't need to be aware. This is great for the
user, and according to the principle of least surprise.

The syntactic sugar of having bash select a free fd (which necessary for
good composability of operations in complex script pipelines) is a great
benefit, especially when mixing with older pipelines having fixed numeric
fd.

You say that there are technical reasons why the syntactic sugar of also
keeping the fd open can't be implemented uniformly.

I wonder if this puts unnecessary cognitive burden on the user, leading to
reluctance to get the benefits, or to the introduction of latent bugs.

There is a case I explain below which can lead to a leaked fd being held on
to by subsequently invoked external processes. Of course it will
technically be the users fault but I'm looking at reducing the cognitive
burdens that make such a fault ultimately inevitable.

The cognitive burdens of leaving the fd open are:

1. It breaks the normal expectation that per-command redirects are limited
to the scope of the command.

A naked exec already works to hold open a variable fd in a wider scope if
that's what the scripter actually wants: exec {fd}>... ;

2. As syntactic sugar it moves, not removes, the boiler-plate burden

This naked exec (see above) saved by the syntactic sugar in the case where
the fd should remain open is offset by the naked exec now required in order
to close the fd for the traditional case that the fd should not left open
beyond the scope of the command.

3. The unmeetable cognitive burden is that in order to safely manage the
previous two item, the user needs to know if the command will be external
or internal or a function.

This makes it hard for the user depend on this feature, because it is not
possible to be sure at script author time whether a command is external. It
may have become a function, (due to export -f, source, etc) which affect
the execution environment.

4. The inevitable propagation of leaked fd's

The knowing user can remember to always use an identity wrapper function to
force treatment as external commands as internal functions in order to get
uniform behaviour, and also explicitly close the fd afterwards. (I hope
this doesn't break exec optimisations or signal propagation over a
different process tree topology, though I doubt it.

But other users may not know to close the fd which was never apparent (due
invoking an external command) but which becomes an fd leak when they
combine with other bash features (functions wrapping of external commands,
or export -f environment that does this unawares) and those leaked fd's may
then be inherited by other invoked external processes which may hold on to
them for some time.

This contrived example minimises the pipeline fd contortions in order to
show that when what was an external command then becomes an internal
command, it can as a consequence result in an fd leak to external processes
(bash+lsof+grep here) which may be long lived.

stty {x}>/tmp/log
bash -c 'lsof -p $$ | grep log ; :'
stty() {
  command stty $EXTRA_STTY "$@"
}
stty {x}>/tmp/log
bash -c 'lsof -p $$ | grep log ; :'

Leading to questions like: "Why does wrapping a one command in a function
cause a different background process to hang on to a private handle not
even used there?"

The future:

I recognise what you say about past design decisions, but for the future,
as it is hard to safely get the benefit of leaving the handle open for
variable per-command redefines, even for users who know about it, I wonder
if the syntactic sugar might be redefined to reduce the cognitive burden
and widen the benefit for the most valued variable fd's feature.

If the variable fd syntactic sugar were re-designed so that variable
handles were also limited to the scope the command, the same as for
external commands, the same as for numeric handles, then:
* the behaviour would be uniform,
* the cognitive burden would be reduced
* and there would be no behaviour dependent on the runtime environment
(export -f to wrap external commands).
* and no risk of unexpected or hard to control fd leaks to subsequent
external (long lived) commands

This would allow users to have full and safe benefit of bash-selected fd's,
which I am sure is what is intended.

I have done my best to be clear in a reasonable manner, but you are the
man, it is your project, we stand or fall by your decisions, not mine.

Sam



On Wed, 

[PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Thomas Deutschmann
At the moment, \h and \H used in prompt PS1 or PS2 will actually return
the same value while manpage claims that \h should return hostname up to
the first '.' (like `hostname`) and \H should return full hostname (like
`hostname -f`).

This commit will make bash use the same API like hostname command to
return full hostname like intended.

This patch is based on the original work from Renato Silva [Link 1].

Link 1: https://lists.gnu.org/archive/html/bug-bash/2014-06/msg00021.html
---
 shell.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/shell.c b/shell.c
index a2b2a55e..28e89a2b 100644
--- a/shell.c
+++ b/shell.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "filecntl.h"
 #if defined (HAVE_PWD_H)
 #  include 
@@ -1839,6 +1840,8 @@ get_current_user_info ()
 static void
 shell_initialize ()
 {
+  struct addrinfo *addr_info;
+  struct addrinfo addr_hints;
   char hostname[256];
   int should_be_restricted;
 
@@ -1864,10 +1867,17 @@ shell_initialize ()
   if (current_host_name == 0)
 {
   /* Initialize current_host_name. */
-  if (gethostname (hostname, 255) < 0)
-   current_host_name = "??host??";
+  memset(&addr_hints, 0, sizeof(struct addrinfo));
+  addr_hints.ai_flags = AI_CANONNAME;
+
+  if (gethostname (hostname, 255) >= 0)
+{
+  if (getaddrinfo (hostname, NULL, &addr_hints, &addr_info) == 0)
+strncpy (hostname, addr_info->ai_canonname, 255);
+  current_host_name = savestring (hostname);
+}
   else
-   current_host_name = savestring (hostname);
+   current_host_name = "??host??";
 }
 
   /* Initialize the stuff in current_user that comes from the password
-- 
2.22.0




Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Chet Ramey
On 7/24/19 9:58 AM, Thomas Deutschmann wrote:
> At the moment, \h and \H used in prompt PS1 or PS2 will actually return
> the same value while manpage claims that \h should return hostname up to
> the first '.' (like `hostname`) and \H should return full hostname (like
> `hostname -f`).

Thanks for the patch. This is system-dependent: there are systems, like
mine, where `hostname' returns the system's FQDN. It all depends on the
administrator's choices.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Thomas Deutschmann
On 2019-07-24 16:27, Chet Ramey wrote:
> Thanks for the patch. This is system-dependent: there are systems, like
> mine, where `hostname' returns the system's FQDN. It all depends on the
> administrator's choices.

Can you tell me more about your system and how you (your administrator)
set up your system so that hostname will return FQDN?

I hope you are not talking about putting FQDN into a file which is
expecting hostname only...

Or in other words: At the moment I am wondering what should be wrong on
my system or on Debian/Ubuntu out of the box: You set hostname to
hostname only (no FQDN) and set domain option in /etc/resolv.conf for
example for FQDN. But maybe I am missing something.

Thanks.


-- 
Regards,
Thomas Deutschmann / Gentoo Linux Developer
C4DD 695F A713 8F24 2AA1 5638 5849 7EE5 1D5D 74A5



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Chet Ramey
On 7/24/19 10:38 AM, Thomas Deutschmann wrote:
> On 2019-07-24 16:27, Chet Ramey wrote:
>> Thanks for the patch. This is system-dependent: there are systems, like
>> mine, where `hostname' returns the system's FQDN. It all depends on the
>> administrator's choices.
> 
> Can you tell me more about your system and how you (your administrator)
> set up your system so that hostname will return FQDN?

I use Mac OS X:

caleb.ins.cwru.edu(1)$ hostname
caleb.ins.cwru.edu
caleb.ins.cwru.edu(1)$ hostname -f
caleb.ins.cwru.edu
caleb.ins.cwru.edu(1)$ uname -a
Darwin caleb.ins.cwru.edu 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25
23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64

> 
> I hope you are not talking about putting FQDN into a file which is
> expecting hostname only...

There is no `file', and there's no requirement that `hostname' not return
the FQDN.

> 
> Or in other words: At the moment I am wondering what should be wrong on
> my system or on Debian/Ubuntu out of the box: You set hostname to
> hostname only (no FQDN) and set domain option in /etc/resolv.conf for
> example for FQDN. But maybe I am missing something.

The world isn't all Linux.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Greg Wooledge
On Wed, Jul 24, 2019 at 04:38:06PM +0200, Thomas Deutschmann wrote:
> Can you tell me more about your system and how you (your administrator)
> set up your system so that hostname will return FQDN?

It's common outside the Linux world.

# hostname
minea.eeg.ccf.org
# uname -a
HP-UX minea B.11.11 U 9000/785 4239047153 unlimited-user license

> I hope you are not talking about putting FQDN into a file which is
> expecting hostname only...

Yes, many people do precisely that.  They configure their systems
so the "hostname" command returns an FQDN, as I showed above.  (Not
my design, not my choice.)

This is what bash's \H vs. \h is for.  If your system's hostname
has dots in it, \h shows only the part up to the first dot (because
that's usually what you want in your prompt -- the shorter version),
and \H is available just in case you actually want the full version.



Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Thomas Deutschmann
On 2019-07-24 16:46, Greg Wooledge wrote:
>> I hope you are not talking about putting FQDN into a file which is
>> expecting hostname only...
> 
> Yes, many people do precisely that.  They configure their systems
> so the "hostname" command returns an FQDN, as I showed above.  (Not
> my design, not my choice.)

I consider this as misconfiguration. :(

I can't believe that we somehow encourage people to either do something
wrong (put FQDN where just non-FQDN is expected and bypass DNS
mechanism) or use $(hostname -f) in PS1 when they want FQDN.

Anyway, back to bash:

So you are rejecting this patch, right? Maybe update man page at least
to clarify that "\H" in contrast to "\h" is supposed to return the same
value but _unfiltered_?

Thanks.


-- 
Regards,
Thomas Deutschmann / Gentoo Linux Developer
C4DD 695F A713 8F24 2AA1 5638 5849 7EE5 1D5D 74A5



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Greg Wooledge
On Wed, Jul 24, 2019 at 05:23:27PM +0200, Thomas Deutschmann wrote:
> On 2019-07-24 16:46, Greg Wooledge wrote:
> >> I hope you are not talking about putting FQDN into a file which is
> >> expecting hostname only...
> > 
> > Yes, many people do precisely that.  They configure their systems
> > so the "hostname" command returns an FQDN, as I showed above.  (Not
> > my design, not my choice.)
> 
> I consider this as misconfiguration. :(
> 
> I can't believe that we somehow encourage people to either do something
> wrong (put FQDN where just non-FQDN is expected and bypass DNS
> mechanism) or use $(hostname -f) in PS1 when they want FQDN.

Your perspective is too limited.  Linux-based systems are very popular,
but they're not the entire Unix world.

# hostname -f
# hostname
-f
# hostname minea.eeg.ccf.org
# 


Personally, I don't like hostname returning a FQDN, but many other
people *do*.  It's common.  When I work on a system that's set that
way, I leave it set that way.

It's so common that bash has two different PS1 escape sequences to
handle it.  Has had them for decades, as far as I know.

There is nothing "wrong" about this configuration.  I don't like it,
and you clearly don't like it, but our opinions only matter to us.



expression evaluation problem

2019-07-24 Thread L A Walsh


shopt -o expand_aliases
my=declare int='my -i'
my str='cf80'
int v=960  uxtra=1  c=0

# In evaluating this expression:
  ((v = v | ( uxtra>=++c ? ((0x${str:2*c:2}) & 63) << (6*(uxtra-c)) : 0 )))


I get 985 and not 960 as expected

Which only happens when 'c' is 0 in the middle 'str' expression,
but the ++c should increment 'c' to '1' before it is tested to be
less than or equal to 'uxtra'(=1).  Then it would take the 1st or
2nd sub expression depending on that.  But the test has to happen
1st, which would pre-increment 'c' to 1.  If 'c' is 1, then it should
return '80' from 'str' combine with 0x to make 0x80 or 128.  That,
anded with '63' should be 0, shouldn't it?

So why isn't it evaluating to '0', 'or'ed  with 960, and giving 960?

Indeed, if I manually put a '1' in place of that 'c' in the middle
of the expression, I get the expected answer of 960.  So it seems
'c' is evaluating as '0', even though the middle sub-expression
can't be taken/evaluated until 'c' has been incremented to 1.

BASH=4.4.12

Thanks
-linda




Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Thomas Deutschmann
On 2019-07-24 17:32, Greg Wooledge wrote:
> Your perspective is too limited.  Linux-based systems are very popular,
> but they're not the entire Unix world.
> 
> [...]
> 
> There is nothing "wrong" about this configuration.  I don't like it,
> and you clearly don't like it, but our opinions only matter to us.

OK :(

Thank you for the explanation!


-- 
Regards,
Thomas Deutschmann / Gentoo Linux Developer
C4DD 695F A713 8F24 2AA1 5638 5849 7EE5 1D5D 74A5



signature.asc
Description: OpenPGP digital signature


Re: expression evaluation problem

2019-07-24 Thread Greg Wooledge
On Wed, Jul 24, 2019 at 09:39:46AM -0700, L A Walsh wrote:
> str='cf80'
> v=960  uxtra=1  c=0

Irrelevant alias shenanigans omitted.  These are your variables.

> # In evaluating this expression:
>   ((v = v | ( uxtra>=++c ? ((0x${str:2*c:2}) & 63) << (6*(uxtra-c)) : 0 )))
> 
> 
> I get 985 and not 960 as expected
> 
> Which only happens when 'c' is 0 in the middle 'str' expression,
> but the ++c should increment 'c' to '1' before it is tested to be
> less than or equal to 'uxtra'(=1).

The ${str:2*c:2} part is performed first, while c is still 0, and it
expands to "cf".

Only then does the arithmetic evaluation begin.

wooledg:~$ str='cf80'
wooledg:~$ v=960  uxtra=1  c=0
wooledg:~$ ((v = v | ( uxtra>=++c ? ((0xcf) & 63) << (6*(uxtra-c)) : 0 )))
wooledg:~$ declare -p v
declare -- v="975"

Even with that parameter expansion out of the way, this arithmetic
command is still ridiculously over-complicated.  I can't even guess
what it's supposed to do.

Have you considered performing your calculation in steps, with
intermediate values stored in temporary variables with clear names?
That greatly improves readability.

Isolating the ++c into its own step would also remove all questions
about whether the increment is performed before or after other
calculations (or in this case, parameter expansions).  In-lining ++c
inside a larger calculation can be OK in very simple situations, but
a nightmare to read/understand/debug in more complex cases.



Explicit variables declaration statements do not resolve back-references from same statement

2019-07-24 Thread Léa Gris
Found this strange behavior difference in Bash, between explicit and 
implicit declarations of variables.


An implicit variables declaration statement resolve back-references to 
variables from the same statement.


Whereas:

An explicit variables declaration statement does not resolve 
back-reference variables from the same statement.


Illustration code:

 knip code start
#!/usr/bin/env bash

unset a b c
printf $'\nExplicit declarations statements:\n'
printf $'\ntypeset -i a=2 b=$a c="$((a - 1))":\n=> '
typeset -i a=2 b=$a c="$((a - 1))"
printf 'a=%d b=%d c=%d\n' "${a}" "${b}" "${c}"
unset a b c
printf $'\ndeclare a=hello b=world c="$a $b":\n=> '
declare a='hello' b='world' c="${a} ${b}"
printf $"a='%s' b='%s' c='%s'\\n" "${a}" "${b}" "${c}"

unset a b c
printf $'\nImplicit declarations statements:\n'
a=2 b=$a c="$((a - 1))"
printf $'\na=2 b=$a c="$((a - 1))":\n=> '
printf 'a=%d b=%d c=%d\n' "${a}" "${b}" "${c}"
unset a b c
a='hello' b='world' c="${a} ${b}"
printf $'\na=hello b=world c="$a $b":\n=> '
printf $"a='%s' b='%s' c='%s'\\n" "$a" "$b" "$c"
 knip code end

Output:

Explicit declarations statements:

typeset -i a=2 b=$a c="$((a - 1))":
=> a=2 b=2 c=1

declare a=hello b=world c="$a $b":
=> ./b.sh[10]: declare: not found [Aucun fichier ou dossier de ce type]
a='' b='' c=''

Implicit declarations statements:

a=2 b=$a c="$((a - 1))":
=> a=2 b=2 c=1

a=hello b=world c="$a $b":
=> a='hello' b='world' c='hello world'


ksh93 resolves explicit back-references with typeset.

--
Léa Gris



signature.asc
Description: OpenPGP digital signature


errata: Explicit variables declaration statements do not resolve back-references from same statement

2019-07-24 Thread Léa Gris
Found this strange behavior difference in Bash, between explicit and 
implicit declarations of variables.


An implicit variables declaration statement resolve back-references to 
variables from the same statement.


Whereas:

An explicit variables declaration statement does not resolve 
back-reference variables from the same statement.


Illustration code:

 knip code start
#!/usr/bin/env bash

unset a b c
printf $'\nExplicit declarations statements:\n'
printf $'\ntypeset -i a=2 b=$a c="$((a - 1))":\n=> '
typeset -i a=2 b=$a c="$((a - 1))"
printf 'a=%d b=%d c=%d\n' "${a}" "${b}" "${c}"
unset a b c
printf $'\ndeclare a=hello b=world c="$a $b":\n=> '
declare a='hello' b='world' c="${a} ${b}"
printf $"a='%s' b='%s' c='%s'\\n" "${a}" "${b}" "${c}"

unset a b c
printf $'\nImplicit declarations statements:\n'
a=2 b=$a c="$((a - 1))"
printf $'\na=2 b=$a c="$((a - 1))":\n=> '
printf 'a=%d b=%d c=%d\n' "${a}" "${b}" "${c}"
unset a b c
a='hello' b='world' c="${a} ${b}"
printf $'\na=hello b=world c="$a $b":\n=> '
printf $"a='%s' b='%s' c='%s'\\n" "$a" "$b" "$c"
 knip code end

Output:
bash ./test_declare.sh 


Explicit declarations statements:

typeset -i a=2 b=$a c="$((a - 1))":
=> a=2 b=0 c=-1

declare a=hello b=world c="$a $b":
=> a='hello' b='world' c=' '

Implicit declarations statements:

a=2 b=$a c="$((a - 1))":
=> a=2 b=2 c=1

a=hello b=world c="$a $b":
=> a='hello' b='world' c='hello world'



ksh93 resolves explicit back-references with typeset.

--
Léa Gris





signature.asc
Description: OpenPGP digital signature


Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread L A Walsh
On 2019/07/24 07:38, Thomas Deutschmann wrote:
> Can you tell me more about your system and how you (your administrator)
> set up your system so that hostname will return FQDN?
>   

My linux box has 2 interfaces, internal & external, with
different domain names on each. While hostname
and hostname-f both return the shortname that is
common to both domain names, i.e.

foo.external.tld(on eth2)
foo.in.external.tld (on br0=bridge(eth0+eth5))
& hostname returns 'foo'
& domainname returns 'external.tld'.

My resolve.conf has domain set to 'in.external.tld'.











Re: expression evaluation problem

2019-07-24 Thread L A Walsh



On 2019/07/24 10:51, Greg Wooledge wrote:
> On Wed, Jul 24, 2019 at 09:39:46AM -0700, L A Walsh wrote:
>   
>> str='cf80'
>> v=960  uxtra=1  c=0
>> 
>
> Irrelevant alias shenanigans omitted.  These are your variables. 
>   

Those aren't my variables.
If you assign the integer attribute to a variable it isn't the same
as when you don't.
>   
>> # In evaluating this expression:
>>   ((v = v | ( uxtra>=++c ? ((0x${str:2*c:2}) & 63) << (6*(uxtra-c)) : 0 )))
>>
>>
>> I get 985 and not 960 as expected
>>
>> Which only happens when 'c' is 0 in the middle 'str' expression,
>> but the ++c should increment 'c' to '1' before it is tested to be
>> less than or equal to 'uxtra'(=1).
>> 
>
> The ${str:2*c:2} part is performed first, while c is still 0, and it
> expands to "cf".
>   
---
Why?  It isn't even necessary when 'c' is greater than 'uxtra'

> Only then does the arithmetic evaluation begin.
>   

Perhaps that such evaluate happens outside of normal evaluation rules is
why shell is so slow?

> wooledg:~$ str='cf80'
> wooledg:~$ v=960  uxtra=1  c=0
> wooledg:~$ ((v = v | ( uxtra>=++c ? ((0xcf) & 63) << (6*(uxtra-c)) : 0 )))
> wooledg:~$ declare -p v
> declare -- v="975"
>
> Even with that parameter expansion out of the way, this arithmetic
> command is still ridiculously over-complicated.  I can't even guess
> what it's supposed to do.
>   
That's because it is a fragment from a program.  It was the minimum
from that program to reproduce the problem.  It's supposed to assign 960
to 'v'.
'v' is for 'value'. 'c' is an integer counter.  uxtra is a limit.
> Have you considered performing your calculation in steps, with
> intermediate values stored in temporary variables with clear names?
> That greatly improves readability.
>   
---
Does it improve execution time?  That's more of a concern here than
readability, since it is an expression fragment, it isn't meant to be
understood
in isolation.

More to the point, how do I get evaluation to occur in arithmetic order?
I.e. so the string operation is done in the order the expression is
evaluated?
> Isolating the ++c into its own step would also remove all questions
> about whether the increment is performed before or after other
> calculations (or in this case, parameter expansions).  In-lining ++c
> inside a larger calculation can be OK in very simple situations, but
> a nightmare to read/understand/debug in more complex cases.
>   
The important part for me is whether or not it is faster to perform
1 calculation, or 100.  So which would be faster?  In this case
execution speed
is more important than clarity.  I consider that a 'constraint'.





Re: [PATCH] Fix \H: Use getaddrinfo to get full hostname

2019-07-24 Thread Chet Ramey
On 7/24/19 11:23 AM, Thomas Deutschmann wrote:
> On 2019-07-24 16:46, Greg Wooledge wrote:
>>> I hope you are not talking about putting FQDN into a file which is
>>> expecting hostname only...
>>
>> Yes, many people do precisely that.  They configure their systems
>> so the "hostname" command returns an FQDN, as I showed above.  (Not
>> my design, not my choice.)
> 
> I consider this as misconfiguration. :(

This is how Mac OS X works in an enterprise environment (this one, at
least).

> I can't believe that we somehow encourage people to either do something
> wrong (put FQDN where just non-FQDN is expected and bypass DNS
> mechanism) or use $(hostname -f) in PS1 when they want FQDN.

Users don't "put" the FQDN anywhere. I didn't do anything when setting
up this system. This is my official hostname as set by enterprise DNS.


> Anyway, back to bash:
> 
> So you are rejecting this patch, right? Maybe update man page at least
> to clarify that "\H" in contrast to "\h" is supposed to return the same
> value but _unfiltered_?

What does `unfiltered' mean that's different from what the man page says?
I don't see the difference.

I think the current implementation is fine, but you can easily use a shell
variable and expand it in $PS1 if you want something other than what
gethostname() gives you.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



signature.asc
Description: OpenPGP digital signature


Re: expression evaluation problem

2019-07-24 Thread Greg Wooledge
On Wed, Jul 24, 2019 at 11:43:11AM -0700, L A Walsh wrote:
> Those aren't my variables.
> If you assign the integer attribute to a variable it isn't the same
> as when you don't.

In this case it *is*, because everything is being fed to an arithmetic
command anyway.

Simplifying the bug report as much as possible lets us avoid
confusing and unnecessary diversions.

> > The ${str:2*c:2} part is performed first, while c is still 0, and it
> > expands to "cf".
> >   
> ---
> Why?  It isn't even necessary when 'c' is greater than 'uxtra'

Because that's how bash works.

  $((expression))

   The expression is treated as if it were within  double  quotes,  but  a
   double  quote inside the parentheses is not treated specially.  All to‐
   kens in the expression undergo parameter and variable  expansion,  com‐
   mand  substitution,  and  quote  removal.  The result is treated as the
   arithmetic expression to be evaluated.  Arithmetic  expansions  may  be
   nested.



Re: errata: Explicit variables declaration statements do not resolve back-references from same statement

2019-07-24 Thread Chet Ramey
On 7/24/19 2:06 PM, Léa Gris wrote:
> Found this strange behavior difference in Bash, between explicit and
> implicit declarations of variables.

It's not that strange.

> An implicit variables declaration statement resolve back-references to
> variables from the same statement.

An assignment statement.

> 
> Whereas:
> 
> An explicit variables declaration statement does not resolve back-reference
> variables from the same statement.

A builtin command performing an assignment on its arguments.

Look at it this way. Since builtins are simple commands, their arguments
are expanded before being invoked. The job of the builtin is to take the
expanded arguments and perform the assignments (values and attributes).
Since the expansions are performed before the builtin is invoked, the
values have not been updated by any previous assignments appearing as
arguments to the builtin.


> ksh93 resolves explicit back-references with typeset.

ksh93 probably does something special to the arguments to typeset so
they're different from other builtins. Bash does some similar things
to implement POSIX's concept of `declaration commands', but those have
mostly to do with the expansions performed on the rhs of the assignment.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



signature.asc
Description: OpenPGP digital signature