Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #263: It's stuck in the Web.


comp / comp.unix.shell / Re: An interesting little quirk - difference between "bash" and "dash" (Linux)

SubjectAuthor
* An interesting little quirk - difference between "bash" and "dash" (Linux)Kenny McCormack
+- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)Kaz Kylheku
+- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)Jerry Peters
+- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)Helmut Waitzmann
`* Re: An interesting little quirk - difference between "bash" and "dash" (Linux)Christian Weisgerber
 `- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)Janis Papanagnou

1
Subject: An interesting little quirk - difference between "bash" and "dash" (Linux)
From: Kenny McCormack
Newsgroups: comp.unix.shell
Organization: The official candy of the new Millennium
Date: Sun, 5 Jan 2025 12:04 UTC
Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gazelle@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.unix.shell
Subject: An interesting little quirk - difference between "bash" and "dash" (Linux)
Date: Sun, 5 Jan 2025 12:04:59 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <vldshb$2jmh6$1@news.xmission.com>
Injection-Date: Sun, 5 Jan 2025 12:04:59 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="2742822"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
View all headers

Consider these two command lines (run from a bash shell, but that's
actually not relevant):

$ bash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
In myfun(), foo =
$ dash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
In myfun(), foo = bar
$

The difference is that in dash, the local foo picks up the value of the
global foo, while in bash, it is empty.

I'm not standards obsessed like some people in these newsgroups; I care
more about desirable functionality. In this case, I would not be surprised
to hear that the dash behavior is more POSIX-ly correct, but it seems clear
to me that the bash behavior is more desirable.

I frequently use "local" precisely to ensure that I get a fresh,
un-initialized variable. Yes, I know that you can always do: local foo=''
but that takes the fun out of it.

--
BigBusiness types (aka, Republicans/Conservatives/Independents/Liberatarians/whatevers)
don't hate big government. They *love* big government as a means for them to get
rich, sucking off the public teat. What they don't like is *democracy* - you know,
like people actually having the right to vote and stuff like that.

Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
From: Kaz Kylheku
Newsgroups: comp.unix.shell
Organization: A noiseless patient Spider
Date: Sun, 5 Jan 2025 20:35 UTC
References: 1
Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: 643-408-1753@kylheku.com (Kaz Kylheku)
Newsgroups: comp.unix.shell
Subject: Re: An interesting little quirk - difference between "bash" and
"dash" (Linux)
Date: Sun, 5 Jan 2025 20:35:02 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 67
Message-ID: <20250105121523.687@kylheku.com>
References: <vldshb$2jmh6$1@news.xmission.com>
Injection-Date: Sun, 05 Jan 2025 21:35:03 +0100 (CET)
Injection-Info: dont-email.me; posting-host="cdd5382b70f6ddd1ee3d22716fea78aa";
logging-data="1265310"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+9Dqp2602bA//gpNP1FROlSVppZBlqXs8="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:QaoeKumjlUr4mYa4C+hT7RSDcX8=
View all headers

On 2025-01-05, Kenny McCormack <gazelle@shell.xmission.com> wrote:
> Consider these two command lines (run from a bash shell, but that's
> actually not relevant):
>
> $ bash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
> In myfun(), foo =
> $ dash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
> In myfun(), foo = bar
> $
>
> The difference is that in dash, the local foo picks up the value of the
> global foo, while in bash, it is empty.
>
> I'm not standards obsessed like some people in these newsgroups; I care
> more about desirable functionality. In this case, I would not be surprised
> to hear that the dash behavior is more POSIX-ly correct, but it seems clear
> to me that the bash behavior is more desirable.
>
> I frequently use "local" precisely to ensure that I get a fresh,
> un-initialized variable.

From your example we know that it is initialized; we don't know that
it's not fresh. If dash lets us can assign to the variable, such that
the global one is affected, then the local means nothing.

Indeed, there is a fresh binding:

$ dash -c 'foo=bar; myfun() { local foo; echo $foo; foo=xyzzy; }; myfun; echo $foo'
bar
bar

It's just that if you don't specify an assignment in local, the
fresh binding inherits the previously visible value.

In Lisp terms:

;; bash semantics:
(let ((*foo*)) ... fresh binding with nil value)

;; dash semantics:
(let ((*foo* *foo*)) ... fresh binding with same value)

The second idiom is crops up in Lisp programming quite a bit; it is
useful to have a fresh binding of a variable which has the current value
so that any modifications of the variable are rolled back when that
scope terminates. (Note that the asterisks in *foo* are just part of
the name; it's the "earmuffs" convention used for naming dynamically
scoped variables. The scope of let is such that in ((*foo* *foo**)),
the scope that is visible to the initializing expression is the
previous one which doesn't yet have the new binding of the variable.

Obviously, if you want portable code between Bash and Dash,
you have to initialize your locals.

> Yes, I know that you can always do: local foo=''
> but that takes the fun out of it.

1. Just local foo= will do.

2. You can always start your code with #!/bin/bash, and forget about
Dash. Portability takes fun out of things, especially when things
have to get ugly or inconvenient.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
From: Jerry Peters
Newsgroups: comp.unix.shell
Organization: A noiseless patient Spider
Date: Sun, 5 Jan 2025 20:37 UTC
References: 1
Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: jerry@example.invalid (Jerry Peters)
Newsgroups: comp.unix.shell
Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
Date: Sun, 5 Jan 2025 20:37:06 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 32
Message-ID: <vleqhh$16m4u$1@dont-email.me>
References: <vldshb$2jmh6$1@news.xmission.com>
Injection-Date: Sun, 05 Jan 2025 21:37:06 +0100 (CET)
Injection-Info: dont-email.me; posting-host="43f233de20a7eb06ba01fe216ebe57ee";
logging-data="1267870"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/hgT5fw5eDfd3f8I+FwCGtBPeHSJCZGY4="
User-Agent: tin/2.4.5-20201224 ("Glen Albyn") (Linux/6.12.7 (x86_64))
Cancel-Lock: sha1:/NevfvVqcQWEAErSzhrUnXxVzl0=
View all headers

Kenny McCormack <gazelle@shell.xmission.com> wrote:
> Consider these two command lines (run from a bash shell, but that's
> actually not relevant):
>
> $ bash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
> In myfun(), foo =
> $ dash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
> In myfun(), foo = bar
> $
>
> The difference is that in dash, the local foo picks up the value of the
> global foo, while in bash, it is empty.
>
> I'm not standards obsessed like some people in these newsgroups; I care
> more about desirable functionality. In this case, I would not be surprised
> to hear that the dash behavior is more POSIX-ly correct, but it seems clear
> to me that the bash behavior is more desirable.
>
> I frequently use "local" precisely to ensure that I get a fresh,
> un-initialized variable. Yes, I know that you can always do: local foo=''
> but that takes the fun out of it.
>

It's optional in bash, see typeset:
The -I option causes local variables to inherit the
attributes (except the nameref attribute) and value of any existing
variable with the same name at a surrounding scope. If there is no
existing variable, the local variable is ini???
tially unset.

That said, I always try to initialize locals if they're not
unconditionally set in the cide.

Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
From: Helmut Waitzmann
Newsgroups: comp.unix.shell
Organization: A noiseless patient Spider
Date: Sun, 5 Jan 2025 21:26 UTC
References: 1
Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: nn.throttle@xoxy.net (Helmut Waitzmann)
Newsgroups: comp.unix.shell
Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
Date: Sun, 05 Jan 2025 22:26:22 +0100
Organization: A noiseless patient Spider
Lines: 53
Sender: Helmut Waitzmann <12f7e638@mail.de>
Message-ID: <831pxhuf41.fsf@helmutwaitzmann.news.arcor.de>
References: <vldshb$2jmh6$1@news.xmission.com>
Reply-To: Helmut Waitzmann Anti-Spam-Ticket.b.qc3c <oe.throttle@xoxy.net>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Injection-Date: Sun, 05 Jan 2025 22:27:36 +0100 (CET)
Injection-Info: dont-email.me; posting-host="6186cac13c7b6533e0589d4c8e40e251";
logging-data="1292159"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19vE52ZgeUDVwKP+HO/frfXETZXHIeB0Rk="
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Cancel-Lock: sha1:q9fNOOgV2yLDTPXfGu70HU46K0I=
sha1:wKmYdd7tJNPw5uWMCDszHK9uZcY=
Mail-Copies-To: nobody
Mail-Reply-To: Helmut Waitzmann Anti-Spam-Ticket.b.qc3c <oe.throttle@xoxy.net>
View all headers

gazelle@shell.xmission.com (Kenny McCormack):
> $ bash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
> In myfun(), foo > $ dash -c 'foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun'
> In myfun(), foo = bar
> $
>
> The difference is that in dash, the local foo picks up the value of the
> global foo, while in bash, it is empty.
>
> I'm not standards obsessed like some people in these newsgroups; I care
> more about desirable functionality. In this case, I would not be surprised
> to hear that the dash behavior is more POSIX-ly correct,
>

I guess, you won't be surprised to read that neither the bash nor
the dash behavior is part of the POSIX standard.

> but it seems clear to me that the bash behavior is more
> desirable.
>
> I frequently use "local" precisely to ensure that I get a fresh,
> un-initialized variable.

Bash won't give you an un‐initialized variable.  It will give you
an modified, emptied variable, while dash will give you an
unmodified variable.

By the way, neither behavior will give you a fresh variable.  Try

(
for shell in bash dash
do
printf '\n%s:\n' "$shell"
"$shell" -c '
foo=bar && readonly -- foo &&
myfun()
{
local foo
printf "In myfun(), foo = %s\n" "$foo"
foo } &&
myfun' "$shell"
done
)

Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
From: Christian Weisgerber
Newsgroups: comp.unix.shell
Date: Sun, 5 Jan 2025 20:27 UTC
References: 1
Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!2.eu.feeder.erje.net!feeder.erje.net!news2.arglkargh.de!news.karotte.org!news.szaf.org!inka.de!mips.inka.de!.POSTED.localhost!not-for-mail
From: naddy@mips.inka.de (Christian Weisgerber)
Newsgroups: comp.unix.shell
Subject: Re: An interesting little quirk - difference between "bash" and
"dash" (Linux)
Date: Sun, 5 Jan 2025 20:27:59 -0000 (UTC)
Message-ID: <slrnvnlqqf.esd.naddy@lorvorc.mips.inka.de>
References: <vldshb$2jmh6$1@news.xmission.com>
Injection-Date: Sun, 5 Jan 2025 20:27:59 -0000 (UTC)
Injection-Info: lorvorc.mips.inka.de; posting-host="localhost:::1";
logging-data="15857"; mail-complaints-to="usenet@mips.inka.de"
User-Agent: slrn/1.0.3 (FreeBSD)
View all headers

On 2025-01-05, Kenny McCormack <gazelle@shell.xmission.com> wrote:

> foo=bar;myfun() { local foo; echo "In myfun(), foo = $foo"; };myfun
>
> I'm not standards obsessed like some people in these newsgroups; I care
> more about desirable functionality. In this case, I would not be surprised
> to hear that the dash behavior is more POSIX-ly correct,

Surprisingly, "local" isn't part of the POSIX shell language at all.

Its only mention is under "If the command name matches the name of
a utility listed in the following table, the results are unspecified".

Is there any POSIX-y shell that does not implement "local"?

--
Christian "naddy" Weisgerber naddy@mips.inka.de

Subject: Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
From: Janis Papanagnou
Newsgroups: comp.unix.shell
Organization: A noiseless patient Spider
Date: Mon, 6 Jan 2025 00:23 UTC
References: 1 2
Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: janis_papanagnou+ng@hotmail.com (Janis Papanagnou)
Newsgroups: comp.unix.shell
Subject: Re: An interesting little quirk - difference between "bash" and
"dash" (Linux)
Date: Mon, 6 Jan 2025 01:23:11 +0100
Organization: A noiseless patient Spider
Lines: 23
Message-ID: <vlf7ph$19b4m$1@dont-email.me>
References: <vldshb$2jmh6$1@news.xmission.com>
<slrnvnlqqf.esd.naddy@lorvorc.mips.inka.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: 7bit
Injection-Date: Mon, 06 Jan 2025 01:23:14 +0100 (CET)
Injection-Info: dont-email.me; posting-host="6777d06973de0b590fb8533f9ecd101b";
logging-data="1354902"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/X7iua/uU98xi02FzCDXGT"
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
Thunderbird/45.8.0
Cancel-Lock: sha1:g6UuyCo0X7PUwCNxTnimzNfDHS0=
In-Reply-To: <slrnvnlqqf.esd.naddy@lorvorc.mips.inka.de>
X-Enigmail-Draft-Status: N1110
View all headers

On 05.01.2025 21:27, Christian Weisgerber wrote:
>
> Surprisingly, "local" isn't part of the POSIX shell language at all.
>
> [...]
>
> Is there any POSIX-y shell that does not implement "local"?

In Kornshell variable-attributes/properties are regularly specified
using 'typeset' and thus the 'typeset' keyword is also used to create
function-"local" variables.

There's no 'local' keyword in Kornshell, and there's also no alias of
that name defined for 'typeset'[*].

Janis

[*] As opposed to the predefined aliases
nameref='typeset -n'
integer='typeset -i'
float='typeset -E'
etc.

1

rocksolid light 0.9.8
clearnet tor