Initialization of variables in the Bourne shells family

Initialization of variables in the Bourne shells family

am 19.09.2007 20:42:06 von michaelgrunewald

In some scripts, one can see

[ -z "$apache22_enable" ] && apache22_enable="NO"

and in some others, the analogue lengthy construction with an _if_
control block. I recently found that

: ${apache22_enable:=NO}

would do, and it seems neat to me. What's the preferred way to
initialize variables?

I've never seen the _colon thing_ anywhere, has anybody?
--
Best regards,
Michaël

Re: Initialization of variables in the Bourne shells family

am 19.09.2007 23:33:28 von Michal Nazarewicz

michaelgrunewald@yahoo.fr (Michaël Grünewald) writes:

> In some scripts, one can see
>
> [ -z "$apache22_enable" ] && apache22_enable="NO"

This fails if you have "set -e". See better example below.

>
> and in some others, the analogue lengthy construction with an _if_
> control block. I recently found that
>
> : ${apache22_enable:=NO}
>
> would do, and it seems neat to me. What's the preferred way to
> initialize variables?

Whatever you like I suppose. Note also that there is a difference
between uninitialised and empty variable, ie.:

[ -n "$foo" ] || foo=bar

will set foo to value bar if it is not set or set to empty value. You
can accomplish the same thing with:

: ${foo:=bar}

however the following:

: ${foo=bar}

will set foo to value bar only if it was not set.
>
> I've never seen the _colon thing_ anywhere, has anybody?

"The colon thing" is a command which returns zero status.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +-------ooO--(_)--Ooo--

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 01:13:27 von Stephane CHAZELAS

2007-09-19, 23:33(+02), Michal Nazarewicz:
> michaelgrunewald@yahoo.fr (Michaël Grünewald) writes:
>
>> In some scripts, one can see
>>
>> [ -z "$apache22_enable" ] && apache22_enable="NO"
>
> This fails if you have "set -e". See better example below.

???

In which shell?

>> and in some others, the analogue lengthy construction with an _if_
>> control block. I recently found that
>>
>> : ${apache22_enable:=NO}
>>
>> would do, and it seems neat to me. What's the preferred way to
>> initialize variables?

The above is quite common.

You also find

apache22_enable=${apache22_enable:-NO}

which can be prefered because there's no word splitting
nor filename generation involved.

: ${apache22_enable:=NO}

could have the side effect of listing some directories and use
some memory uselessly.

: "${apache22_enable:=NO}"

is better, but then some shells have problems if you try to do
things like:

: "${apache22_enable:=some value}"

Compare for instance:

apache22_enable='/*/*/*/../../../*/*/*/../../../*/*/*'
: ${apache22_enable:=NO}

with:

apache22_enable='/*/*/*/../../../*/*/*/../../../*/*/*'
apache22_enable=${apache22_enable:-NO}

In Bourne like shells other than zsh.

The first one has already been known to crash some systems, and
it can still make some unusable for a few seconds.

Even in this case, leaving a variable unquoted can have nasty
side effects.

--
Stéphane

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 01:51:42 von Michal Nazarewicz

Stephane CHAZELAS writes:

> 2007-09-19, 23:33(+02), Michal Nazarewicz:
>> michaelgrunewald@yahoo.fr (Michaël Grünewald) writes:
>>
>>> In some scripts, one can see
>>>
>>> [ -z "$apache22_enable" ] && apache22_enable="NO"
>>
>> This fails if you have "set -e". See better example below.
>
> ???
>
> In which shell?

Oh... Sorry... I could have sworn that I had problems with such
expression.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +-------ooO--(_)--Ooo--

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 09:04:04 von michaelgrunewald

Stephane CHAZELAS writes:

> You also find
>
> apache22_enable=${apache22_enable:-NO}
>
> which can be prefered because there's no word splitting
> nor filename generation involved.
>
> : ${apache22_enable:=NO}
>
> could have the side effect of listing some directories and use
> some memory uselessly.

Thank you for this precision and the example you put along. While
comparing these ways to initialize variables I had not the variable
splitting/expansion stuff in mind.

I was pleased by the `colon construction' because of it looked a bit
like the `?=' operator in BSD Make. I was not aware of the possible
side effect in the `colon construction'.
--
All the best,
Michaël

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 09:21:42 von Stephane CHAZELAS

2007-09-20, 09:04(+02), Michaël Grünewald:
> Stephane CHAZELAS writes:
>
>> You also find
>>
>> apache22_enable=${apache22_enable:-NO}
>>
>> which can be prefered because there's no word splitting
>> nor filename generation involved.
>>
>> : ${apache22_enable:=NO}
>>
>> could have the side effect of listing some directories and use
>> some memory uselessly.
>
> Thank you for this precision and the example you put along. While
> comparing these ways to initialize variables I had not the variable
> splitting/expansion stuff in mind.
>
> I was pleased by the `colon construction' because of it looked a bit
> like the `?=' operator in BSD Make. I was not aware of the possible
> side effect in the `colon construction'.

It's not that much the side effect of the "colon construction"
as such, it's the side effect of leaving a variable (or a
command substitution) unquoted.

You'll get the same problem if you ommit the quotes in

echo $apache22_enable

(which in this case is even doubly wrong because of the usage of
echo in addition to the non-quoted variable).

In anycase, for a variable that is to contain either YES or NO,
it won't do much of a difference, but it's something to be aware
of to start and get good habits.

--
Stéphane

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 14:50:49 von michaelgrunewald

Stephane CHAZELAS writes:

> You'll get the same problem if you ommit the quotes in
>
> echo $apache22_enable
>
> (which in this case is even doubly wrong because of the usage of
> echo in addition to the non-quoted variable).

I am so naive that I do not know what is so wrong with the `echo'
shell primitive! I spotted elsethread that

printf "%s\n" "$apache22_enable"

has some advantages on

echo "$apache22_enable"

but I do not really see them. Would you mind giving a clue about this?
--
All the best,
Michaël

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 16:28:47 von Stephane CHAZELAS

2007-09-20, 14:50(+02), Michaël Grünewald:
[...]
> I am so naive that I do not know what is so wrong with the `echo'
> shell primitive! I spotted elsethread that
>
> printf "%s\n" "$apache22_enable"
>
> has some advantages on
>
> echo "$apache22_enable"
>
> but I do not really see them. Would you mind giving a clue about this?

A Unix echo expands strings like "\n", "\t"... to LF, TAB.

A POSIX echo may or may not do that, and may or may not fail to
output "-n" if apache22_enable=-n. Some implementations of echo
even have other restrictions.

So echo is an unreliable and not portable utility to output an
arbitrary string of text.

printf '%s\n' "$var"

doesn't have any of those issues.

--
Stéphane

Re: Initialization of variables in the Bourne shells family

am 20.09.2007 17:11:04 von michaelgrunewald

Thanks for these precisions.
--
Cheers,
Michaël

Re: Initialization of variables in the Bourne shells family

am 23.09.2007 00:22:20 von Sven Mascheck

Michal Nazarewicz wrote:
> Stephane CHAZELAS writes:
>> 2007-09-19, 23:33(+02), Michal Nazarewicz:

>>>> [ -z "$apache22_enable" ] && apache22_enable="NO"
>>>
>>> This fails if you have "set -e".
>>
>> In which shell?
>
> Oh... Sorry... I could have sworn that I had problems with such
> expression.

Have you been working with Ultrix?

The above is true for Version 7 like Bourne shells, the first variant.
Ultrix was famous for having such a shell as /bin/sh in all releases.

Re: Initialization of variables in the Bourne shells family

am 23.09.2007 00:49:02 von Michal Nazarewicz

Sven Mascheck writes:

> Michal Nazarewicz wrote:
>> Stephane CHAZELAS writes:
>>> 2007-09-19, 23:33(+02), Michal Nazarewicz:
>
>>>>> [ -z "$apache22_enable" ] && apache22_enable="NO"
>>>>
>>>> This fails if you have "set -e".
>>>
>>> In which shell?
>>
>> Oh... Sorry... I could have sworn that I had problems with such
>> expression.
>
> Have you been working with Ultrix?

No I haven't. The only shells I've been using were bash, zsh, oryginal
Bourne Shell as found in Solaris, ash (the version nowadays provided
with some Linuxes) and pdksh.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +------ooO--(_)--Ooo--