Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

status on $[arith] for eval arith vsl $((arith))??

23 views
Skip to first unread message

Linda Walsh

unread,
Apr 7, 2012, 4:45:55 PM4/7/12
to bug-bash



In modifying some released code on my distro, I ran into the
extensive use
of $[arith] as a means for returning arithmetic evaluations of the
expression.

I vaguely remember something like that from years ago, but never see any
reference to
it -- yet it works, and old code seems to rely on it -- and
"$[(1+2)/3]" looks cleaner than "$(((1+2)/3))". So what's up with that?

If it wasn't designed to run in non-bash environments, I might think it was
an artifact of array evaluation.. I.e. with no array name after $,
instead of that
number being used as an index for the array, it's returned as a raw
value... but
I've seen it in code designed for 'sh'...

Is it an accidental omission from the bash manpage?






Mike Frysinger

unread,
Apr 7, 2012, 5:09:15 PM4/7/12
to bug-...@gnu.org, Linda Walsh
On Saturday 07 April 2012 16:45:55 Linda Walsh wrote:
> Is it an accidental omission from the bash manpage?

it's in the man page. read the "Arithmetic Expansion" section.
-mike
signature.asc

Linda Walsh

unread,
Apr 7, 2012, 5:50:17 PM4/7/12
to Mike Frysinger, bug-...@gnu.org
====
My 4.2 manpage says:

Arithmetic Expansion
Arithmetic expansion allows the evaluation of an arithmetic expression
and the substitution of the result. The format for arithmetic expan-
sion is:

$((expression))

The expression is treated as if it were within double quotes, but a
double quote inside the parentheses is not treated specially. All
tokens in the expression undergo parameter expansion, string expansion,
command substitution, and quote removal. Arithmetic expansions may be
nested.

The evaluation is performed according to the rules listed below under
ARITHMETIC EVALUATION. If expression is invalid, bash prints a message
indicating failure and no substitution occurs.

----------
No mention of square brackets.

What's yours say?



Pierre Gaston

unread,
Apr 7, 2012, 6:02:16 PM4/7/12
to Linda Walsh, bug-...@gnu.org
Some linux distributions patch the man page and document $[ ] as deprecated.

The SUS rationale says:

In early proposals, a form $[expression] was used. It was functionally
equivalent to the "$(())" of the current text, but objections were
lodged that the 1988 KornShell had already implemented "$(())" and
there was no compelling reason to invent yet another syntax.
Furthermore, the "$[]" syntax had a minor incompatibility involving
the patterns in case statements.

Chet Ramey

unread,
Apr 7, 2012, 7:47:13 PM4/7/12
to Linda Walsh, bug-bash, chet....@case.edu
On 4/7/12 4:45 PM, Linda Walsh wrote:
>
>
>
> In modifying some released code on my distro, I ran into the extensive use
> of $[arith] as a means for returning arithmetic evaluations of the
> expression.
>
> I vaguely remember something like that from years ago, but never see any
> reference to
> it -- yet it works, and old code seems to rely on it -- and
> "$[(1+2)/3]" looks cleaner than "$(((1+2)/3))". So what's up with that?

It dates from Posix circa 1990 (1003.2d9, of which I've lost my paper
copy). I implemented it after the Berkeley guys, mostly Marc
Teitelbaum, put it into Posix. It ended up getting dropped in favor
of the ksh $((...)) expansion, at which point everyone deprecated the
old $[...]. I removed it from the manual sometime later, but it still
works as it always has.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU ch...@case.edu http://cnswww.cns.cwru.edu/~chet/

Chris F.A. Johnson

unread,
Apr 8, 2012, 3:11:45 PM4/8/12
to Linda Walsh, bug-bash
On Sat, 7 Apr 2012, Linda Walsh wrote:

> In modifying some released code on my distro, I ran into the extensive use
> of $[arith] as a means for returning arithmetic evaluations of the
> expression.
>
> I vaguely remember something like that from years ago, but never see any
> reference to
> it -- yet it works, and old code seems to rely on it -- and
> "$[(1+2)/3]" looks cleaner than "$(((1+2)/3))". So what's up with that?

At the minor expense of a few extra keystrokes, $(( (1+2) / 3 ))
looks just as clean, and has the added cachet of being portable.

--
Chris F.A. Johnson, <http://cfajohnson.com/>
Author:
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)

Chet Ramey

unread,
Apr 8, 2012, 3:30:45 PM4/8/12
to Maarten Billemont, Linda Walsh, bug-bash, chet....@case.edu
On 4/8/12 3:02 PM, Maarten Billemont wrote:

> Any particular reason for not removing old undocumented functionality, or is that mostly the nature of this beast - dragging along and maintaining ancient code for the sake of compatibility?=

Because, as Linda discovered, there is still working code out there using
it. Maybe we'll get to a point where it's all gone, but we're not there
yet.

dethrophes

unread,
Apr 8, 2012, 5:17:32 PM4/8/12
to bug-...@gnu.org
ever thought of going the depreciation route.
Something like what microsoft do with vc.

I.e. give a warning for depreciated constructs. With a hint as to how to
do it better?

Linda Walsh

unread,
Apr 9, 2012, 5:46:43 AM4/9/12
to Maarten Billemont, bug-bash, chet....@case.edu


Maarten Billemont wrote:

> On 08 Apr 2012, at 21:30, Chet Ramey wrote:
>> On 4/8/12 3:02 PM, Maarten Billemont wrote:
>>
>>> Any particular reason for not removing old undocumented functionality, or is that mostly the nature of this beast - dragging along and maintaining ancient code for the sake of compatibility?=
>> Because, as Linda discovered, there is still working code out there using
>> it. Maybe we'll get to a point where it's all gone, but we're not there
>> yet.
>
>
> IMO, the working code out there that relies on $[...] either runs on older versions of bash.

Actually it was a version of 'sh',

Seems like it it's also in 'zsh'. I note.



or if the sysadmin decided to upgrade bash, he can assume the responsibility to fix the code.

Might be a good reason to ditch bash and stick with something that supports a
syntax that's been around for 20 years.

Like it costs how much? I would **bet** that it cost more code to support (())
than to support [] as arith ops .. so if you want my opinion, lets toss (())...
(like that'll happen)...

[] is 1 token -- (()) is a double token. (()) is much less legible because it
is used IN the expressions [] isn't a grouping operator in an arith expression.

Also if you start with $((, that doesn't mean what follows is a arith
expression...as in
$(((1)) && echo ok) -- only arith expression is after the 3rd paren.

$(()) for arith expressions is ugly!.... -- since the $ on the outside of (())
changes it meaning visually it is more ambiguous... Why $[] wasn't used makes
no sense -- unless someone did it the other way just to make political waves...
as seems to often be the outlet of frustrated and unimportant people -- if they
can make others lives more miserable, then they have created their own importance.

*plegh*...




Aharon Robbins

unread,
Apr 9, 2012, 9:03:16 AM4/9/12
to
In article <mailman.795.133396...@gnu.org>,
Linda Walsh <ba...@tlinx.org> wrote:
>>> Because, as Linda discovered, there is still working code out there using
>>> it. Maybe we'll get to a point where it's all gone, but we're not there
>>> yet.
>>
>> IMO, the working code out there that relies on $[...] either runs on
>>older versions of bash.
>
>Actually it was a version of 'sh',

On many GNU/Linux systems, sh is a link to bash.

>Might be a good reason to ditch bash and stick with something that supports a
>syntax that's been around for 20 years.

You might want to start at http://www2.research.att.com/~gsf/download/ to
get the current source code for ksh93.

> Like it costs how much? I would **bet** that it cost more code to support
> (()) than to support [] as arith ops .. so if you want my opinion,
> lets toss (())...

As has been pointed out, for better or for worse, $((...)), is existing
practice (from ksh93) and is what is standardized by POSIX. I suspect
that many people would agree with you w.r.t. aethestics, code maintainability,
and so on.

Unfortunately, in the case of the shell language, and many other nooks
and crannies of the Unix toolset, it's just plain too late to change.
(You might want to find a copy of the Unix version of the 'rc' shell,
which shows the results of one person's starting over from scratch.)

As has also been pointed out, although possibly not too recently in
this forum, membership in the POSIX working groups is open to anyone
who wishes to participate. It is a worthwhile experience (I was involved
in POSIX in the early 1990s), and *that* truly is the way to influence
the standards and the code that implements them.
--
Aharon (Arnold) Robbins arnold AT skeeve DOT com
P.O. Box 354 Home Phone: +972 8 979-0381
Nof Ayalon Cell Phone: +972 50 729-7545
D.N. Shimshon 99785 ISRAEL

Linda Walsh

unread,
Apr 9, 2012, 9:07:03 PM4/9/12
to Maarten Billemont, bug-bash, chet....@case.edu


Maarten Billemont wrote:

> Any particular reason for not removing old undocumented functionality,


or is that mostly the nature of this beast - dragging along and maintaining


ancient code for the sake of compatibility?


----

So 'yesturday' is "ancient" for you?... that's really means something.

In doing a scan over my /usr partition,
I see MANY examples in bash 4.1 in it's examples of using $[] -- I would hardly
call 4.1 "ancient".


Other packages that make use of the syntax:

* wondershaper
* cifs file system
* alsa (sound)
* fonts-config (this is a new project within the past few years)
* QT4
* GoogleBrowser (chromium)
* RPM
* YP
* PM Utils
* RPMrebuild
* iproute2 (almost all modern internet functions on linux)...
* dhcp-client
- (zsh -- not a real example, but might become alternate system shell if bash
killed $[] support)
* Opera - ? (has comment "TODO use $(()) instead of $[] whenever possible;...)
"whenever possible??"
* samba
and a HUGE number in
** linux-kernel -- all over the place...

At that point, I was getting too many to keep up with ... so I stopped searching...

$[] has is -- I would bet, Universally, used MORE than $(())...

Chet -- you should get back to the posix folks and tell them posix is to be
'descriptive of usage' (their words), not prescriptive. Just because ksh did
it differently from everyone else's usage doesn't mean they should go with that
syntax...

Geez.





Chet Ramey

unread,
Apr 9, 2012, 10:47:24 PM4/9/12
to Linda Walsh, chet....@case.edu, bug-bash, Maarten Billemont
On 4/9/12 9:07 PM, Linda Walsh wrote:
>
>
> Maarten Billemont wrote:
>
>> Any particular reason for not removing old undocumented functionality,
>> or is that mostly the nature of this beast - dragging along and maintaining
>> ancient code for the sake of compatibility?

>
> So 'yesturday' is "ancient" for you?... that's really means something.

You have a peculiar view of history (spelling and grammar, too, but we'll
leave that aside).

>
> In doing a scan over my /usr partition,
> I see MANY examples in bash 4.1 in it's examples of using $[] -- I would
> hardly call 4.1 "ancient".

True, I never went back and changed the examples.

>
>
> Other packages that make use of the syntax:
>
> * wondershaper
> * cifs file system
> * alsa (sound)
> * fonts-config (this is a new project within the past few years)
> * QT4
> * GoogleBrowser (chromium)
> * RPM
> * YP
> * PM Utils
> * RPMrebuild
> * iproute2 (almost all modern internet functions on linux)...
> * dhcp-client
> - (zsh -- not a real example, but might become alternate system shell if bash
> killed $[] support)
> * Opera - ? (has comment "TODO use $(()) instead of $[] whenever
> possible;...) "whenever possible??"
> * samba
> and a HUGE number in
> ** linux-kernel -- all over the place...
>
> At that point, I was getting too many to keep up with ... so I stopped
> searching...
>
> $[] has is -- I would bet, Universally, used MORE than $(())...

I believe you'd lose, but it's unprovable either way. Consider the fact,
though, that bash and zsh support $[...], ksh93 and dash support only
$((...)), but that all four support $((...)).

> Chet -- you should get back to the posix folks and tell them posix is to be
> 'descriptive of usage' (their words), not prescriptive. Just because ksh
> did it differently from everyone else's usage doesn't mean they should go
> with that syntax...

You have got to be kidding. Don't you realize you're talking about
decisions that are nearly 20 years old? That $[...] was a Posix
invention that only ever appeared in P1003.2d9? That the $((...))
syntax was adopted officially for P1003.2-1992? That's 1992. Twenty
years ago.

Bash, and later zsh, implemented $[...] because there was no other
syntax at the time, and to gain some operational experience with
arithmetic expansion in the shell. Bash-1.14 (the oldest I have
readily available) lists both forms of arithmetic expansion, but by
the time bash-2.0 was released in 1995, the manual referred only to
the $((...)) form. That's 17 years ago. Hardly "yesterday".

Now, it's hardly any problem to keep dragging the $[...] syntax along.
It takes only a few dozen bytes of code. I have no plans to remove it.
But let's not kid ourselves: it's revisionist history to think that
$[...] was widespread before Posix so callously stamped it out.

> Geez.

Indeed.

Elliott Forney

unread,
Apr 10, 2012, 12:22:05 AM4/10/12
to chet....@case.edu, Linda Walsh, bug-bash, Maarten Billemont
My two cents, would be to add a bit to the man page that says something like:

-------
For historical reasons, the following format is also supported for
arithmetic evaluation:

$[expression]

Note, however, that this format is non-standard and that
$((expression)) is preferred.
-------

At least that way there won't be an undocumented feature.

Thanks,
Elliott Forney

Chet Ramey

unread,
Apr 10, 2012, 10:59:13 AM4/10/12
to Maarten Billemont, Linda Walsh, bug-bash, chet....@case.edu
On 4/10/12 3:33 AM, Maarten Billemont wrote:

> If we were to move to $[ ... ]

But we're not. It's ludicrous to think we would. How far down the rabbit
hole are we going to go on this?

Chet Ramey

unread,
Apr 10, 2012, 11:00:52 AM4/10/12
to Elliott Forney, Linda Walsh, Maarten Billemont, bug-bash, chet....@case.edu
On 4/10/12 12:22 AM, Elliott Forney wrote:
> My two cents, would be to add a bit to the man page that says something like:
>
> -------
> For historical reasons, the following format is also supported for
> arithmetic evaluation:
>
> $[expression]
>
> Note, however, that this format is non-standard and that
> $((expression)) is preferred.
> -------
>
> At least that way there won't be an undocumented feature.

I don't mind an undocumented feature in this case, since the only reason
it's there is being carried along for backwards compatibility.

Linda Walsh

unread,
Apr 11, 2012, 5:34:01 AM4/11/12
to bug-bash


Chet Ramey wrote:

> On 4/9/12 9:07 PM, Linda Walsh wrote:
>>
>> ** linux-kernel -- all over the place...
>>
>> At that point, I was getting too many to keep up with ... so I stopped
>> searching...
>>
>> $[] has is -- I would bet, Universally, used MORE than $(())...
>
> I believe you'd lose, but it's unprovable either way. Consider the fact,
> though, that bash and zsh support $[...], ksh93 and dash support only
> $((...)), but that all four support $((...)).

----

Well, I think you are probably right -- looks like alot of newer more
bash-specific, and 'clever' code uses (())... but it isn't easy on the eyes...


But the examples of use of $(()) are leaning far more toward the perverse side
than simple use of $[]...

Maybe lisp programmers prefer (())??

a few examples:


- options="$(expr "${options}" : "\(.\{$((${last_option_index}-1))\}\)")"
- YESTERDAY=$(date -r $((`date +%s` - 86400 )) +%d/%m/%Y
- PREGAP=$(($(echo $OFFSETS | cut -f1 -d' ')))

- for ((vl=$((v_level - 1)); $vl > 0; --vl))

Using [] in expressions provides a distinct visual feature that is
different from the content.... There's no unclarity in confusing it
with $(xxx) $((xxx)) if xxx is a var and a function, which did they mean?

You don't hae that issue with $[], as to confuse it with an array, you'd
have to leave off the array name and the curly brackets...
======================================================================
Maarten Billemont wrote:

> (Don't give

> me the spiel about how [...] is already arithmetic evaluation
> inside array indices, that's a different syntax entirely,

How is that? I thought it WAS the syntax.

${xxx[yyy]} => remove the array base, and you just get a calculated
offset as a result

=> $[yyy]...

It is similar to C in that regard. You can put [xxx] after an ID, and it
means it is an array # of items past the array's start. but if the array was
missing. (well besides the syntax errors), it would just be the offset.



>>> BTW, in case there is any doubt, I am not pushing for removal of $(()), or
a change of the status quo, but I am taking issue with the idea of removing $[],
as some proposed...




>> Chet -- you should get back to the posix folks and tell them posix is to be
>> 'descriptive of usage' (their words), not prescriptive. Just because ksh
>> did it differently from everyone else's usage doesn't mean they should go
>> with that syntax...
>
> You have got to be kidding. Don't you realize you're talking about
> decisions that are nearly 20 years old? That $[...] was a Posix
> invention that only ever appeared in P1003.2d9? That the $((...))
> syntax was adopted officially for P1003.2-1992? That's 1992. Twenty
> years ago.

====


> Now, it's hardly any problem to keep dragging the $[...] syntax along.
> It takes only a few dozen bytes of code. I have no plans to remove it.
> But let's not kid ourselves: it's revisionist history to think that
> $[...] was widespread before Posix so callously stamped it out.

----
I've seen it more often in portable code than the $(()) -- but I
could be remembering it more because it stands out too...


>
>> Geez.
>
> Indeed.

>

Indubitably.
:-)


Greg Wooledge

unread,
Apr 11, 2012, 8:11:19 AM4/11/12
to Linda Walsh, bug-bash
On Wed, Apr 11, 2012 at 02:34:01AM -0700, Linda Walsh wrote:
> - for ((vl=$((v_level - 1)); $vl > 0; --vl))

The inside of the for ((...)) is already a math context. You don't need
another $((...)) inside it.

for ((vl = v_level - 1; vl > 0; --vl))

Or is that another "irrelevant detail"?

Linda Walsh

unread,
Apr 12, 2012, 1:01:12 AM4/12/12
to Greg Wooledge, bug-bash
Um... Why do you think I included it --
I NEVER saw anything like that where [] was used... people
seem to not understand the (()) is arith, but you need $(()) to get
the value out of the insides...



But the examples of use of $(()) are leaning far more toward the perverse side
than simple use of $[]..
a few examples:

- options="$(expr "${options}" : "\(.\{$((${last_option_index}-1))\}\)")"
- YESTERDAY=$(date -r $((`date +%s` - 86400 )) +%d/%m/%Y
- PREGAP=$(($(echo $OFFSETS | cut -f1 -d' ')))

- for ((vl=$((v_level - 1)); $vl > 0; --vl))

---------------------

It's irrelevant to 'function', but not to efficiency or readability.

But hey, gold star for paying attention! ;-)

(those are all examples from various system scripts in /usr...





Andreas Schwab

unread,
Apr 12, 2012, 3:48:27 AM4/12/12
to Linda Walsh, Greg Wooledge, bug-bash
Linda Walsh <ba...@tlinx.org> writes:

> - YESTERDAY=$(date -r $((`date +%s` - 86400 )) +%d/%m/%Y

This fails around autumn DST transition (assuming s/-r /-d @/).

YESTERDAY=$(date -d '12:00 yesterday' +%d/%m/%Y)

Andreas.

--
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."

0 new messages