Discussion:
Maybe off topic: Where is bash gesture ${X=Y} described ?
(too old to reply)
Thomas Schmitt
2024-07-24 13:40:01 UTC
Permalink
Hi,

maybe i am just too dumb to read the manual, or maybe i made an
archeological discovery in the shells we use.

I came to a strange shell gesture which i find neither in man bash nor
man dash. Nevertheless it works the same in both shells.

GRUB's test scripts often show this gesture

: "${TMPDIR=/tmp}"

Well known and described is
${X:=Y}
which assigns a default value to variable X if it is empty (man bash
says: "If [...] unset or null").
Also known and described is ":", the no-op command.
So
: "${TMPDIR:=/tmp}"
would not be a riddle. But "=" instead ":=" causes a subtle change in
behavior. A defined but empty variable does not get the default content:

$ unset x
$ : ${x=YYY}
$ echo $x
YYY
$ x=
$ : ${x=YYY}
$ echo $x

$

With ":=" the empty variable gets a new stuffing:

$ : ${x:=YYY}
$ echo $x
YYY
$

The dash shell instead of bash shows the same behavior.

Is this legacy behavior ?
Are there shells which do ${X=Y} but not ${X:=Y} ?

--------------------------------------------------------------------
Reason why i ask:

I came to that gesture while trying to find out why a run of GRUB's
"make check" as superuser left a lot of empty directories in the
/-directory, Most GRUB tests do early

: "${TMPDIR=/tmp}"

or use variable expansion with default value: ${TMPDIR:-/tmp}
But tests/grub_cmd_cryptomount uses TMPDIR naively so that its test
directories end up as
/1718898505.LUKS1_test_cryptsetup_defaults
...
/1718912880.LUKS2_test_with_second_key_slot_and_first_slot_using_different_password

I would like to talk GRUB into using ${X:=Y} generally, because it does
not matter whether TMPDIR is defined empty or is unset.
So i need background knowledge about the currently used ${X=Y}.

(One may say that is not a good idea to run a test as superuser.
But most GRUB tests create and mount filesystems. So after a change in
the tool grub-fstest i had to do it as superuser to check for new test
failures caused by my change. It was only one and that was expected.)


Have a nice day :)

Thomas
Greg Wooledge
2024-07-24 14:00:01 UTC
Permalink
Post by Thomas Schmitt
GRUB's test scripts often show this gesture
: "${TMPDIR=/tmp}"
Well known and described is
${X:=Y}
which assigns a default value to variable X if it is empty (man bash
says: "If [...] unset or null").
Also known and described is ":", the no-op command.
So
: "${TMPDIR:=/tmp}"
would not be a riddle. But "=" instead ":=" causes a subtle change in
$ man bash
[...]
Parameter Expansion
[...]
When not performing substring expansion, using the forms documented be‐
low (e.g., :-), bash tests for a parameter that is unset or null.
Omitting the colon results in a test only for a parameter that is un‐
set.

${parameter:-word}
Use Default Values. [...]


Everyone skips over the sentence that begins with "Omitting the colon".

Every time we try to tell Chet, "Hey, man, please add examples that
show BOTH syntaxes", he blows us off, because this is the way POSIX
documents it. If it's good enough for POSIX, then it must be good
enough for bash, right?[1]

Ordinary users search for the SYNTAX. Then when they find a list of
examples, they only read that list. They don't read the text BEFORE
the list. They might read text AFTER the list, but even that's rare.

This is why I created <https://mywiki.wooledge.org/BashSyntaxReference>.
You can look up syntax there and see what it does.


[1]Hmm, it looks like POSIX added a table:
<https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_06_02>
actually shows both forms, if you scroll down a bit.
t***@tuxteam.de
2024-07-24 14:10:01 UTC
Permalink
On Wed, Jul 24, 2024 at 09:50:36AM -0400, Greg Wooledge wrote:

[...]
Post by Greg Wooledge
Everyone skips over the sentence that begins with "Omitting the colon".
Thanks for this one. I know /I/ did for long enough.

Greg, this place would be a lot less helpful...
Post by Greg Wooledge
Every time we try to tell Chet, "Hey, man, please add examples that
show BOTH syntaxes" [...]
...and definitely more boring without you. Thanks for that :-)

Cheers
--
t
Thomas Schmitt
2024-07-24 14:10:02 UTC
Permalink
Hi,
Post by Greg Wooledge
Post by Thomas Schmitt
maybe i am just too dumb to read the manual, or maybe i made an
archeological discovery in the shells we use.
Everyone skips over the sentence that begins with "Omitting the colon".
Oh well. Too dumb and not alone.

I did read the sentence immediately before "Omitting the colon".

In man dash the statement comes after the list of modifications:

In the parameter expansions shown previously, use of the colon in the
format results in a test for a parameter that is unset or null; omission
of the colon results in a test for a parameter that is only unset.

If there would be written ":" instead of "colon" i might have passed the
brain agility test.


Have a nice day :)

Thomas
Max Nikulin
2024-07-25 02:10:01 UTC
Permalink
Post by Greg Wooledge
Everyone skips over the sentence that begins with "Omitting the colon".
Every time we try to tell Chet, "Hey, man, please add examples that
show BOTH syntaxes", he blows us off, because this is the way POSIX
documents it. If it's good enough for POSIX, then it must be good
enough for bash, right?[1]
For a long time I was believing that ${X=Y} is just an obsolete and less
strict form of ${X:=Y} due to the way it is documented in BASH. Once I
needed to distinguish empty an unset values. First hits in search engine
results gave me impression that people just did not care. Fortunately I
spotted <https://stackoverflow.com/a/16753536> with both variants (a
quote from POSIX). I agree that colon vs. no colon should be documented
in a more prominent way.

Loading...