Re: exiting noninteractive shells on 'shift 2'

2018-11-08 Thread Grisha Levit
On Thu, Nov 8, 2018, 3:48 PM Eric Blake  wrote:

>  If the n operand is invalid or is greater than "$#", this may be
> considered a syntax error and a non-interactive shell may exit; if the
> shell does not exit in this case, a non-zero exit status shall be
> returned.


This seems to say that "shift N" *may* be considered an error *in which
case* the rules in 2.8.1 must apply. But since bash does not consider it to
be an error, it behaves as the second half of the sentence proscribes and
returns a non-zero status.

>


Re: exiting noninteractive shells on 'shift 2'

2018-11-08 Thread Chet Ramey
On 11/8/18 3:37 PM, Eric Blake wrote:
> If I'm reading POSIX correctly, shift is a special built-in utility, and if
> '$#' is 0 or 1, then 'shift 2' counts as a utility error that shall exit
> the shell, per the table in 2.8.1 Consequences of Shell Errors:
> 
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_01
> 
> 
> 
> dash gets this right:
> 
> $ dash -c 'set 1
>> shift 2
>> echo "oops"'
> dash: 2: shift: can't shift that many
> 
> but bash happily lets 'shift 2' fail with $? set to 1 but continues on with
> execution of the rest of the script, even when in POSIX mode:

As you later note:

"If the n operand is invalid or is greater than "$#", this may be
considered a syntax error and a non-interactive shell may exit; if the
shell does not exit in this case, a non-zero exit status shall be returned.
Otherwise, zero shall be returned."

So the bash behavior is not a conformance issue, and allowed by the
standard.

-- 
``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/



exiting noninteractive shells on 'shift 2'

2018-11-08 Thread Eric Blake
If I'm reading POSIX correctly, shift is a special built-in utility, and 
if '$#' is 0 or 1, then 'shift 2' counts as a utility error that shall 
exit the shell, per the table in 2.8.1 Consequences of Shell Errors:


http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_01


dash gets this right:

$ dash -c 'set 1
> shift 2
> echo "oops"'
dash: 2: shift: can't shift that many

but bash happily lets 'shift 2' fail with $? set to 1 but continues on 
with execution of the rest of the script, even when in POSIX mode:


$ bash -c 'set 1
> shift 2
> echo "oops"'
oops
$ bash -c 'set 1; set -o posix
> shift 2
> echo "oops"'
oops

I spent more than an hour today figuring out why my shell script was 
inf-looping, and traced it back to failure to check for non-zero status 
from 'shift 2', where I had been expecting immediate hard failure of the 
entire script.  I don't care if bash doesn't hard-exit when not in POSIX 
mode, and it must not hard-exit when in interactive use; but the 
non-interactive use not doing a hard exit seems like a bug.


On the other hand, the POSIX wording for shift, under EXIT STATUS, 
weakens the "shall fail" from the earlier table into a weaker "may fail":


http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#shift

If the n operand is invalid or is greater than "$#", this may be 
considered a syntax error and a non-interactive shell may exit; if the 
shell does not exit in this case, a non-zero exit status shall be 
returned. Otherwise, zero shall be returned.


Tested on Fedora 28 with bash-4.4.23-1.fc28.x86_64

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: The builtin array variable 'FUNCNAME' is considered unset by many expansions, even when set.

2018-11-08 Thread Chet Ramey
On 11/8/18 10:28 AM, Great Big Dot wrote:
>> It should expand to the empty string in all these cases.
> 
> Oh yeah, right, because a function isn't even running. Duh. All my comments
> about expected behavior should be inverted, then, I guess. Out of
> curiosity, do you have any idea what's causing bash to *sometimes*
> correctly conclude that FUNCNAME[0] is empty and other times that
> FUNCNAME[*] is empty, under seemingly arbitrary circumstances? I can't
> figure out what could be causing that.

Yes. The internal function that returns an array value isn't honoring the
`not visible' setting. That's where the change needs to be.

-- 
``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: The builtin array variable 'FUNCNAME' is considered unset by many expansions, even when set.

2018-11-08 Thread Great Big Dot
> It should expand to the empty string in all these cases.

Oh yeah, right, because a function isn't even running. Duh. All my comments
about expected behavior should be inverted, then, I guess. Out of
curiosity, do you have any idea what's causing bash to *sometimes*
correctly conclude that FUNCNAME[0] is empty and other times that
FUNCNAME[*] is empty, under seemingly arbitrary circumstances? I can't
figure out what could be causing that.

On Thu, Nov 8, 2018 at 9:57 AM Chet Ramey  wrote:

> On 11/8/18 1:15 AM, Great Big Dot wrote:
>
> > Bash Version: 4.4
> > Patch Level: 23
> > Release Status: release
> >
> > Description:
> > The builtin array variable FUNCNAME (which provides a way to trace the
> > stack of functions called so far) appears to be unset according to
> certain
> > bash expansions, even when it isn't. If the following code is saved to a
> > file and executed (this doesn't work at the command line), the problems
> > begin to appear:
> >
> > printf -- '%q\n' "${FUNCNAME}"
> > printf -- '%q\n' "${FUNCNAME[0]}"
> > printf -- '%q\n' "${FUNCNAME[*]}"
>
> Thanks for the report. It should expand to the empty string in all these
> cases.
>
> --
> ``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: The builtin array variable 'FUNCNAME' is considered unset by many expansions, even when set.

2018-11-08 Thread Great Big Dot
> Since your example doesn't show a function being defined or called, I
> would expect it to show only empty strings.

Oh yeah, right. For some reason I thought the part about "main" still
applied. But the actual expected behavior doesn't occur either;
"${FUNCNAME[0]}" and "${FUNCNAME[*]}" are both nonempty! I thought
"${FUNCNAME}" was the incorrect one since it alone was empty, but it turns
out that's the only one that's correct.

> Also, as a side note, "${x}" and "${x[0]}" are always the same.  Literally
> always.  Doesn't matter what type of variable x is (or isn't).

That's what I thought too, before finding this bug. When executing from a
file, "${FUNCNAME[0]}" exists but "${FUNCNAME}" doesn't. I incorrectly
thought the latter was wrong, but the inconsistency is still there!



On Thu, Nov 8, 2018 at 8:28 AM Greg Wooledge  wrote:

> On Thu, Nov 08, 2018 at 01:15:56AM -0500, Great Big Dot wrote:
> > Description:
> > The builtin array variable FUNCNAME (which provides a way to trace the
> > stack of functions called so far) appears to be unset according to
> certain
> > bash expansions, even when it isn't. If the following code is saved to a
> > file and executed (this doesn't work at the command line), the problems
> > begin to appear:
> >
> > printf -- '%q\n' "${FUNCNAME}"
> > printf -- '%q\n' "${FUNCNAME[0]}"
> > printf -- '%q\n' "${FUNCNAME[*]}"
>
> I don't see any functions there.  From the manual:
>
>FUNCNAME
>   [...]
>   This  variable  exists  only when a shell function is
> executing.
>   Assignments to FUNCNAME have no effect.  If FUNCNAME  is
> unset,
>   it  loses  its  special  properties,  even if it is
> subsequently
>   reset.
>
> Since your example doesn't show a function being defined or called, I
> would expect it to show only empty strings.
>
> Also, as a side note, "${x}" and "${x[0]}" are always the same.  Literally
> always.  Doesn't matter what type of variable x is (or isn't).
>
>


Re: The builtin array variable 'FUNCNAME' is considered unset by many expansions, even when set.

2018-11-08 Thread Chet Ramey
On 11/8/18 1:15 AM, Great Big Dot wrote:

> Bash Version: 4.4
> Patch Level: 23
> Release Status: release
> 
> Description:
> The builtin array variable FUNCNAME (which provides a way to trace the
> stack of functions called so far) appears to be unset according to certain
> bash expansions, even when it isn't. If the following code is saved to a
> file and executed (this doesn't work at the command line), the problems
> begin to appear:
> 
> printf -- '%q\n' "${FUNCNAME}"
> printf -- '%q\n' "${FUNCNAME[0]}"
> printf -- '%q\n' "${FUNCNAME[*]}"

Thanks for the report. It should expand to the empty string in all these
cases.

-- 
``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: The builtin array variable 'FUNCNAME' is considered unset by many expansions, even when set.

2018-11-08 Thread Greg Wooledge
On Thu, Nov 08, 2018 at 01:15:56AM -0500, Great Big Dot wrote:
> Description:
> The builtin array variable FUNCNAME (which provides a way to trace the
> stack of functions called so far) appears to be unset according to certain
> bash expansions, even when it isn't. If the following code is saved to a
> file and executed (this doesn't work at the command line), the problems
> begin to appear:
> 
> printf -- '%q\n' "${FUNCNAME}"
> printf -- '%q\n' "${FUNCNAME[0]}"
> printf -- '%q\n' "${FUNCNAME[*]}"

I don't see any functions there.  From the manual:

   FUNCNAME
  [...]
  This  variable  exists  only when a shell function is executing.
  Assignments to FUNCNAME have no effect.  If FUNCNAME  is  unset,
  it  loses  its  special  properties,  even if it is subsequently
  reset.

Since your example doesn't show a function being defined or called, I
would expect it to show only empty strings.

Also, as a side note, "${x}" and "${x[0]}" are always the same.  Literally
always.  Doesn't matter what type of variable x is (or isn't).