Re: An interesting little quirk - difference between "bash" and "dash" (Linux)

Liste des GroupesRevenir à cu shell 
Sujet : Re: An interesting little quirk - difference between "bash" and "dash" (Linux)
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.unix.shell
Date : 05. Jan 2025, 21:35:02
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250105121523.687@kylheku.com>
References : 1
User-Agent : slrn/pre1.0.4-9 (Linux)
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

Date Sujet#  Auteur
5 Jan 25 * An interesting little quirk - difference between "bash" and "dash" (Linux)6Kenny McCormack
5 Jan 25 +- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)1Kaz Kylheku
5 Jan 25 +- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)1Jerry Peters
5 Jan 25 +- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)1Helmut Waitzmann
5 Jan 25 `* Re: An interesting little quirk - difference between "bash" and "dash" (Linux)2Christian Weisgerber
6 Jan 25  `- Re: An interesting little quirk - difference between "bash" and "dash" (Linux)1Janis Papanagnou

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal