[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Is bash dying or dead (was Re: 4.1 is "$((( ))) an 'official operato
Re: Is bash dying or dead (was Re: 4.1 is "$((( ))) an 'official operator, if $(( )) isn't?
Wed, 10 Aug 2011 17:44:39 -0700
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:126.96.36.199) Gecko/20100228 Thunderbird/188.8.131.52 Mnenhy/0.7.6.666
Eric Blake wrote:
On 08/10/2011 03:59 PM, Linda Walsh wrote:
Is this a fluke, due to the above changes NOT being 4.1? Or is this
construction going to break in 4.2:
According to POSIX, this construction should be parsed as an arithmetic
substitution $(()) where the expression is (expr),
I was going by this note by chet:
No. The code is in there for a reason. It's part of the fix for
interpretation 217 (http://austingroupbugs.net/view.php?id=217).
Maybe I misunderstood the Posix verbage (not a far stretch), but it said:
0000217: The "single subshell" rule for $(( is not sufficient
Description In the description of command substitution the standard says:
If the command substitution consists of a single subshell, such as:
$( (command) )
a conforming application shall separate the "$(" and '(' into two
tokens (that is, separate them with white space). This is required
to avoid any ambiguities with arithmetic expansion.
In a discussion on the mailing list in December 2009, Philip Guenther
demonstrated that there are ambiguous cases other than the "single
subshell" case. He gave the example:
cat=1; EOH=3; echo $(( cat <<EOH
+ ( (
) && ( cat <<EOH
) ) + 1 +
Current shell implementations treat this as an arithmetic expansion.
Thus the requirement on applications quoted above should be extended
to cover all ambiguous cases, not just the "single subshell" case.
The same requirement should also apply to nested subshells, so that
shells which implement the "(( arithmetic expression ))" extension
can apply the same disambiguation rules consistently to $((...)) and
It sounded to me like $(( )) would be translated into "$( (xxxx) )",
turning off arithmetic expansion. Did I read that incorrectly?
If not, then wouldn't
$((( ))) be turned into $( (( )) ), meaning the arith returns a status,
and not the calculation. (I've tested this, and this is the case.
if at all possible;
but if not possible, then it may also be parsed as a command
substitution $() around either a double-subshell (()) or a shell
extension of an arithmetic evaluation.
And since POSIX correctly states that this is implementation-specific,
and involves shell heuristics, you are best off adding spaces to make it
explicit which form you intended.
I wanted to evaluate something and assign result to a var.
gives me 'a=0', but
Not portable - lack of spacing means you fall foul of the ambiguity traps.
Where would I add spacing? Adding spacing after $( and before )
causes wrong eval.
a=$( ((-48-16+2**6)) )
will give 'a=<nothing>' -- understandable since the arith expression
merely sets status, it doesn't yield up it's value.
I'm NOT concerned with portability to other shells!
A requirement of my programs is that they be run by bash -- I use so
many bash extensions
that rewriting to some 50% subset would put me off shell for another 10
While bash happened to use (( as an arith expression,
other shells may treat it as a double-subshell, and try to execute the
You mean like this
Ishtar:law> a=$( ((-48-16+2**6)))
Ishtar:law> echo $a
Your suggestion doesn't work -- and THAT is my point.
There is little in the way of a workaround.
if you intended to assign a to the arithmetic expansion of the
expression (-48-16+2**6); however, you are _still_ falling foul of using
a bash extension (not all shells understand ** in arithmetic
Whatever, 2*32....that wasn't the point.
If I use:
((a=-48-16+2**6)) ; throws an error. if -e is on, script exits
Bash extension. But the exit status of (()) makes sense as being
non-zero for a result of 0, since the intended use of (()) is in control
loops where the loop counter reaching 0 should abort the loop.
And in a loop it is TESTED... while ((xxxx)), if ((xxxx), etc.
In those cases it WON't abort a script (usually)...it returns the result
conditional which does the 'right thing'. It's when it is used as a simple
calculation and NOT as a value for a conditional that NOW causes the
problem -- it
didn't used to.
the exit status makes sense, then the interaction with 'set -e' makes
sense. Rather, you should realize that 'set -e', when rigidly defined,
causes what seem to be very unintuitive results, and that NO AMOUNT OF
COMPLAINING will ever make it more intuitive, so you are better off
learning how to properly script without using 'set -e' as a crutch.
This didn't used to be true -- so don't claim that it IS 'true', as it's
a arbitrary decision that may be true at some point in time, and false
at other times.
I.e. it isn't inherently true -- only because of the 'new' convention --
truth was that it didn't abort. and that truth has alot more history
Since 'let' functions the same as the above, then
'let' is a bash extension, not portable to POSIX.
Again, posix=don't care, let it function that way under the --posix switch.
(I didn't know let was a bash extension...)
Seems like POSIX has made bash as useful (or less so in some ways) as
Not true. POSIX has made bash more useful by making the portable
constructs well-defined whether you are running on bash or any other
portable shell, while still leaving bash room to provide extensions like
(()) and let.
That's only if you use other shells -- if a pre-req of your product is
on bash, then it's a 'deficit'. Not alot of people DON't have access
It seems like POSIX is trying to kill off the usefulness of Bash -- and
that Bash is becoming 'sh+', rather than 'Bash'.
Not true. Join the Austin Group,
Oh, I'm sure they'd love me...
< and you will see that the goal of
POSIX is to standardize existing practice into something that can be
commonly implemented by multiple people and safely relied on by multiple
existing scripts, rather than worrying about implementation-specific
extensions all over the place. If you can code to a common subset, your
program becomes much more useful in practice.
I agree, but you can't program to the standard MS-API, and expect it to
unix with any great easy (successes of wine aside). If you want
portability -- then put the
posix stuff in --posix, that is what it is FOR! But by making bash
into posix compat, you lose advantages in bash.
POSIX is braindead.
I'm sorry you think so, but ranting on this list won't change POSIX.
I dunno if it was entirely a 'rant', I didn't just go off on posix. I
what I felt were valid reasons why it was a problem. Ranting is just
going on, and
not really justifying your position.
you don't like what POSIX is doing, then join the Austin Group
(membership is free of charge) and submit your suggestions for
You, Chet and the Austin group _may_ rue the day when you said this.
Bash shouldn't follow posix unless in --posix mode, as posix mode is
worthless to program in -- as evidenced by the fact that you can no
longer do any calculation safely with let or (()),
'let' and (()) are not specified by POSIX, so you can't portably use
them in --posix mode in the first place. --posix is VERY useful; it is
what allows you to write scripts that work in bash, dash, ksh, zsh, and
several other shells, without having to rewrite them every time you copy
the script to a new machine.
Then why enforce posix semantics on them? If they are not of posix,
not let them operate in 'useful mode'
without fear that
your script will randomly die (oh just don't use command-exit-error
checking...) and you can no longer call functions safely.
'set -e' and function calls are one of the _fundamental_ non-intuitive
designs of the historical shell. They were designed independently, and
do not interact well.
I've always had them act predictably -- I found them invaluable in
as they'd stop where an error occurred and require me to fix. Not
it goes on to future dependent steps that get very confused and can do
'bad thinks if previous steps didn't work.
But given the latest POSIX wording, you can at
least apply consistent rules and rationally explain each behavior that
you are seeing, and why what appears unintuitive actually complied with
the standard; and you _can't_ change that non-intuitiveness without
breaking existing scripts that have come to rely on the quirks as
currently codified by POSIX.. The problem was that even in POSIX 2008,
the POSIX wording had holes, it is not until the TC1 wording that the
wording was tightened enough to actually be implementable by bash in a
manner that matched ksh.
Where there ya go. That's the problem I _used_ to use ksh when it
came out but when base came along, it was SO much better. ksh should be
to match bash. The problem with software in general is poeple aiming
for the lowest
Bash is becoming very unstable -- programs that work in 3.1 won't
necessarily work in 3.2, those in 3.2 aren't compat with 4.0, 4.0 is
different than 4.1, and now 4.2 is different than 4.1.
That's because older bash has had bugs where it doesn't comply with
POSIX, and those bugs have been fixed, but sometimes the fixes have
consequences on the bash extensions. But if you use the POSIX subset,
rather than the bash extensions, you should notice that newer bash is
better, not worse, than older bash when it comes to running portable
EXACTLY -- if people want posix strictures, they should use it.
How can people write stable scripts in an enironment of constant change?
By sticking to the common denominator that is known to work.
In other words, by ignoring everything that is 'bash', and sticking
in which case bash is worth less than nothing, as it takes up more
memory and resources than
posix compat shells like ash and ksh. The whole point of bash was to
have MORE than posix.
Please people, am I being 'over-reactive'? Or are these valid
At least in my view, you are coming across as over-reactive and ranting,
even if that was not your intent.
I can easily believe you feel that, that's why I asked -- I wonder too
-- it seems
like such an important issue, but so many don't seem to care, and it
drives me crazy
(but then the world is like that in just about every field)
So I don't discount what you say, but I don't think you are seeing my
bash being many 'ease of use/easy of programming' extensions on top of
the POSIX base. It
is for those things that have made bash the # linux shell. If it
becomes another ksh, then
what's the point?
peace and more sadness than 'ranting'...