NetBSD Problem Report #47597
From julio+host-netbsd-jmmv@meroh.net Tue Feb 26 02:42:45 2013
Return-Path: <julio+host-netbsd-jmmv@meroh.net>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
by www.NetBSD.org (Postfix) with ESMTP id 4BC0F63E522
for <gnats-bugs@gnats.NetBSD.org>; Tue, 26 Feb 2013 02:42:45 +0000 (UTC)
Message-Id: <20130226024241.D2C233528A9@netbsd.meroh.net>
Date: Mon, 25 Feb 2013 21:42:41 -0500 (EST)
From: julio+host-netbsd-jmmv@meroh.net
Reply-To: julio+host-netbsd-jmmv@meroh.net
To: gnats-bugs@NetBSD.org
Subject: local and $() don't play well with each other
X-Send-Pr-Version: 3.95
>Number: 47597
>Category: bin
>Synopsis: local and $() don't play well with each other
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Feb 26 02:45:00 +0000 2013
>Last-Modified: Tue Feb 26 08:25:02 +0000 2013
>Originator: Julio Merino
>Release: NetBSD 6.99.17
>Organization:
>Environment:
System: NetBSD netbsd.meroh.net 6.99.17 NetBSD 6.99.17 (GENERIC) #0: Sat Feb 23 07:37:14 EST 2013 jmmv@netbsd.meroh.net:/home/jmmv/os/merge/amd64/obj/home/jmmv/os/merge/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
The following test case exhibits an error with /bin/sh and /bin/ksh
that does not happen with bash:
-----
f() {
echo "before setting var"
local var=$(echo a=b --c=d)
echo "var is: ${var}"
echo "after setting var"
}
echo "before calling f"
f
echo "after calling f"
-----
Running this script with /bin/sh results in the following output:
-----
$ sh ~/test.sh
before calling f
before setting var
var is: a=b
after setting var
/home/jmmv/test.sh: --c: bad variable name
-----
And with /bin/ksh:
-----
$ ksh ~/test.sh
before calling f
before setting var
/home/jmmv/test.sh[11]: typeset: --c=d: not identifier
after calling f
-----
Surrounding the $() with double quotes makes this work with both
shells and mimics the behavior of bash.
I don't know what the expected correct behavior here is, so I cannot
tell if this is a bug or not. Filing one just in case.
What strikes me as really odd is the fact that sh is raising the
error when the function f returns, not when var is assigned to.
>How-To-Repeat:
Just see above for the test case and the observed behavior.
>Fix:
Don't know if there is anything to fix...
>Audit-Trail:
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/47597: local and $() don't play well with each other
Date: Tue, 26 Feb 2013 14:03:58 +0700
Date: Tue, 26 Feb 2013 02:45:01 +0000 (UTC)
From: julio+host-netbsd-jmmv@meroh.net
Message-ID: <20130226024501.278CE63F087@www.NetBSD.org>
| I don't know what the expected correct behavior here is, so I cannot
| tell if this is a bug or not.
I do not believe there is any expected behaviour, the script is beyond the
bounds of what is intended.
The man page for sh says that the syntax for local is
local [variable | -] ...
Nothing about assigning values as well. That it works even partly is
something of a fluke I'd think.
The special rule about quotes not being required around variable assignments
applies only when they are leading assignments on a (possibly null) command,
not whenever an '=' appears in a command line anywhere.
When you do (what is effectively)
local a=b -c
you'd be amazed if that assigned "b -c" to a, but that's just what your
script does, as word splitting happens after command substitution.
Since local isn't a standardised operator as best I can tell (pity about that)
shells are free to implement it differently, and apparently, do.
The correct way to do what you're trying (as best as "local" can ever be
correct - which is not to bad, as just about all shells support it) is
f() {
local var
var=$(echo a=b --c=d) # and now the special quoting rule applies
}
Also, for what it is worth, the other issue you reported:
| What strikes me as really odd is the fact that sh is raising the
| error when the function f returns, not when var is assigned to.
doesn't occur for me on NetBSD 6/i386 - the error is raised on the assignment
(are you sure you just didn't see some artifact of mixing stderr & stdout
in a peculiar way)?
kre
ps I don't want to try and fathom ksh's convoluted mechanism for local, and
how its syntax should work in this case... bash explicitly allows variable
assignments in a local command.
From: David Laight <david@l8s.co.uk>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/47597: local and $() don't play well with each other
Date: Tue, 26 Feb 2013 08:38:00 +0000
On Tue, Feb 26, 2013 at 02:45:01AM +0000, julio+host-netbsd-jmmv@meroh.net wrote:
> >Number: 47597
> >Category: bin
> >Synopsis: local and $() don't play well with each other
> Machine: amd64
> >Description:
> The following test case exhibits an error with /bin/sh and /bin/ksh
> that does not happen with bash:
>
> -----
> f() {
> echo "before setting var"
> local var=$(echo a=b --c=d)
> echo "var is: ${var}"
> echo "after setting var"
> }
A much simpler test shows the same feature:
(x="a b"; b=fubar; export y=$x; echo $y; sh -c 'echo $b')
Depending on the shell you either get the effect of:
export y="a b"
or:
export y=a b
The SUS is, as usual, tortuous. But export is a 'special builtin utility'
so runs after normal command line processing - which includes field
splitting.
So, for export and readonly, the netbsd shells are conformant.
I think the bash man page has a specific note about the way export (etc)
are parsed.
'local' isn't in the standard.
David
--
David Laight: david@l8s.co.uk
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.