Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bug batch

6 views
Skip to first unread message

Dan Douglas

unread,
Jun 13, 2013, 2:14:09 AM6/13/13
to bug-...@gnu.org
Hello,

Clearing out the remainder of my "maybe bugs" file, in no particular order.

1. Arithmetic assignment precedence / associativity.

Most shells (and GCC) consider not grouping the assignment in a situation like
this an error. Bash tolerates it, apparently reversing associativity:

: $((1 == x = 1)) # Error in dash/ksh/mksh/zsh/etc

#include <stdio.h>
int main() {
int n;
5 == n = 5 && printf("%d\n", n); // Error
return 0;
}

2. += environment assignments

2a. POSIX mode += w/ special builtin.

#!/usr/bin/env bash
for sh in bash ~/doc/programs/bash43 ksh mksh zsh; do
printf '%-7s %s\n' "${sh##*/}:" "$("$sh" /dev/fd/0)"
done <<\EOF
${ZSH_VERSION+false}${BASH_VERSION+${POSIXLY_CORRECT=}}||emulate ksh
x=2; x+=5 eval printf '"$x "'; echo "$x" # TESTCASE
EOF

shell | inner | outer
bash: 5 2 #(4.2.45)
bash43: 5 5
ksh: 25 25
mksh: 25 25
zsh: 25 25

2b. Integer attribute with += environment assignment.

The manual doesn't document an exception for += when a command is present. Some
shells do arithmetic for += with a command (bash doesn't).

#!/usr/bin/env bash
for sh in bash ~/doc/programs/bash43 ksh mksh zsh; do
printf '%-7s %s\n' "${sh##*/}:" "$("$sh" /dev/fd/0)"
done <<\EOF
${ZSH_VERSION+false}${BASH_VERSION+${POSIXLY_CORRECT=}}||emulate ksh
typeset -i x=2
x+=5 eval printf '"$x "'; echo "$x" # TESTCASE
EOF

bash: 5 2
bash43: 5 5
ksh: 7 7
mksh: 25 25
zsh: 7 7

3. RETURN trap doesn't fire upon leaving a function via break or continue.

This is a very minor possibly intentional detail. The way break works in this
situation is interesting -- maybe useful.

function f {
case $1 in
3) while :; do f $(($1 - 1)) done
;;
0)
trap "printf \$1" RETURN
break
;;
*) f $(($1 - 1))
esac
}

# Prints "345" instead of "12345"
f 5

4. Invalid compound assignments can become string assignments.

If the first character of a regular assignment is an unquoted "(", then if
there's a a matching ")", the remainder of the assignment up to the next
unquoted metacharacter is assigned as a string. Zsh and ksh honor the ")" of
a compound assignment as a metacharacter (to separate commands). mksh and dash
treat such an assignment as an error.

$ x=()abc; typeset -p x # It might be better to require quoting here.
declare -- x="()abc"
$ ksh -xc 'x=(foo)typeset -p x'
+ x=( foo )
+ typeset -p x
typeset -a x=(foo)

5. Easter egg (test + redirect + $[])

$ trap 'echo "$BASH_COMMAND"; trap - DEBUG' DEBUG
$ [ <& $[ ] [ = [ && printf '%s\n' "$_ ...ha :)"
[ [ = [ 0<&$[ ]
[ ...ha :)

I like this. :)

6. Indirection combined with another modifier expands arrays to a single word.

$ a=({a..c}) b=a[@]; printf '<%s> ' "${!b}"; echo; printf '<%s> ' "${!b/%/foo}"; echo
<a> <b> <c>
<a b cfoo>

I might have already reported this but can't find it. Ignore if so.

--
Dan Douglas

Linda Walsh

unread,
Jun 13, 2013, 5:54:57 AM6/13/13
to bug-...@gnu.org
I can't speak to all your cases, but I had comments on a few:



Dan Douglas wrote:

> Most shells (and GCC) consider not grouping the assignment in a situation like
> this an error. Bash tolerates it, apparently reversing associativity:
>
> : $((1 == x = 1)) # Error in dash/ksh/mksh/zsh/etc
----
If you do it without the ':', it returns a false status.
The colon doesn't seems to return true or false based on whether or not
there was a syntactic error, but not for a command that runs normally and returns
any status.


> 2. += environment assignments
>
> 2a. POSIX mode += w/ special builtin.
>
You say you got an answer of '2'? When I did your test interactively,
it came out '25' in non-posix mode. (bash V 4.2.45). I have a feeling
that you asked for posix (dysfunctional) and got it. I don't recall
the posix standard specifying "+=" as an operator, but I'm FAR from an
expert on posix.

> shell | inner | outer
> bash: 5 2 #(4.2.45)
> bash43: 5 5
> ksh: 25 25
> mksh: 25 25
> zsh: 25 25
>
....
Anyway, don't have time to analyze the rest, but those above looked
like bash is doing the right thing...?

Chris Down

unread,
Jun 13, 2013, 6:07:43 AM6/13/13
to Linda Walsh, bug-bash
On 13 Jun 2013 11:00, "Linda Walsh" <ba...@tlinx.org> wrote:
> If you do it without the ':', it returns a false status.
> The colon doesn't seems to return true or false based on whether or not
> there was a syntactic error, but not for a command that runs normally and
returns
> any status.

: is just a noop that happens to return true. Any syntactic problems would
be raised by bash, not :.

Dan Douglas

unread,
Jun 13, 2013, 6:24:28 AM6/13/13
to bug-...@gnu.org
On Thursday, June 13, 2013 02:54:57 AM Linda Walsh wrote:
> I can't speak to all your cases, but I had comments on a few:
>
> Dan Douglas wrote:
>
> > Most shells (and GCC) consider not grouping the assignment in a situation
> > like this an error. Bash tolerates it, apparently reversing associativity:
> >
> > : $((1 == x = 1)) # Error in dash/ksh/mksh/zsh/etc
> ---- If you do it without the ':', it returns a false status. The colon
> doesn't seems to return true or false based on whether or not there was a
> syntactic error, but not for a command that runs normally and returns any
> status.

The colon and status aren't relevant to this test. It's an illegal arithmetic
expression because the comparison should be evaluated before the assignment,
throwing a fatal shell error because the assignment lacks an identifier on the
LHS. It might not cause any ambiguity the way Bash is currently doing it, it
just won't warn of the ensuing portability problem.

> > 2. += environment assignments
> >
> > 2a. POSIX mode += w/ special builtin.
> >
> You say you got an answer of '2'? When I did your test interactively, it
> came out '25' in non-posix mode. (bash V 4.2.45). I have a feeling that you
> asked for posix (dysfunctional) and got it. I don't recall the posix
> standard specifying "+=" as an operator, but I'm FAR from an expert on posix.

+= isn't POSIX. You won't get the same results in non-POSIX mode because the
eval won't leak its environment. I don't expect POSIX mode to affect the
behavior of +=, but it provides extra information that isn't apparent in
non-POSIX mode in this case.

The main thing being demonstrated here is the difference from 4.2 - 4.3 and the
fact that it isn't appending to the previous value. Bash in POSIX mode should
be closer to the other shells being compared.

> .... Anyway, don't have time to analyze the rest, but those above looked
> like bash is doing the right thing...?

It doesn't apply modified behavior for the -i attribute. AFAICT, that isn't
documented and is possibly unintentional.

--
Dan Douglas


Eric Blake

unread,
Jun 13, 2013, 6:42:15 AM6/13/13
to Dan Douglas, bug-...@gnu.org
On 06/13/2013 11:24 AM, Dan Douglas wrote:
> On Thursday, June 13, 2013 02:54:57 AM Linda Walsh wrote:
>> I can't speak to all your cases, but I had comments on a few:
>>
>> Dan Douglas wrote:
>>
>>> Most shells (and GCC) consider not grouping the assignment in a situation
>>> like this an error. Bash tolerates it, apparently reversing associativity:
>>>
>>> : $((1 == x = 1)) # Error in dash/ksh/mksh/zsh/etc
>> ---- If you do it without the ':', it returns a false status. The colon
>> doesn't seems to return true or false based on whether or not there was a
>> syntactic error, but not for a command that runs normally and returns any
>> status.
>
> The colon and status aren't relevant to this test. It's an illegal arithmetic
> expression because the comparison should be evaluated before the assignment,
> throwing a fatal shell error because the assignment lacks an identifier on the
> LHS. It might not cause any ambiguity the way Bash is currently doing it, it
> just won't warn of the ensuing portability problem.

POSIX says that any $(()) expression that cannot be parsed as arithmetic
is then evaluated as if it were $( ( 1 == x = 1 ) ) (that is, a command
substitution of a subshell that attempts to invoke the command named
'1'). This is not a syntax error, but is an error if there is no
command named '1'.

Whether various shells have extensions that attempt to treat the command
as arithmetic or fall back to command substitution is a different
matter, since POSIX doesn't forbid extensions.

--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org

signature.asc

Dan Douglas

unread,
Jul 28, 2013, 1:20:50 AM7/28/13
to bug-...@gnu.org
Testing on amd64/Gentoo:

On Thursday, June 13, 2013 01:14:09 AM you wrote:
> Hello,
>
> Clearing out the remainder of my "maybe bugs" file, in no particular order.
>
> 1. Arithmetic assignment precedence / associativity.

fixed.

> 2. += environment assignments
>
> 2a. POSIX mode += w/ special builtin.

fixed.

> 2b. Integer attribute with += environment assignment.

fixed.

> 3. RETURN trap doesn't fire upon leaving a function via break or continue.

I don't really care about this.

> 4. Invalid compound assignments can become string assignments.

Same.

> 6. Indirection combined with another modifier expands arrays to a single word.

fixed.

:-)

--
Dan Douglas

0 new messages