[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: If the variable has its 'integer' attribute set,



On Sun, Nov 21, 2021 at 01:37:14AM +0000, sim sim wrote:
> I do not understand  "If the variable has its 'integer' attribute set," where the variable has an 'integer' attribute, after all, this is not a function?

They're talking about "declare -i".  Which is really a stupid thing
and I wish it didn't exist, but it does, and people are silly enough
to use it, and I cannot stop them.

For those who don't understand the context of the question, this is
about bash, and variables in bash.

All variables in bash hold string values.  Even if you use "declare -i",
the value that is stored in memory is a string.  What "declare -i" does
is make it so that when you assign new strings to the variable, dark
magic occurs.  The value that gets assigned will be interpreted by the
shell's math context parser, and the result will be a value that looks
like a number, or else an error.

unicorn:~$ bash
unicorn:~$ declare -i foo
unicorn:~$ foo=bar
unicorn:~$ declare -p foo
declare -i foo="0"

So... what happened here?  We tried to assign the string "bar" to a
variable with the "-i" flag set.  Since bar doesn't look like a number,
it was sent into the math context parser.  The math context parser saw
that "bar" looks like a variable name, so it recursively evaluated "bar"
in a math context, retrieve the value from the variable "bar".  Which
did not exist.  So that value was assigned as "0".  Which is a string that
looks like a number.  Because, as I said, all bash variables hold strings.

unicorn:~$ bar='hello world'
unicorn:~$ foo=bar
bash: hello world: syntax error in expression (error token is "world")

Here, we got an error, because "hello world" could not be evaluated by
the shell's math parser.

unicorn:~$ bar=7*9
unicorn:~$ foo=bar
unicorn:~$ declare -p foo bar
declare -i foo="63"
declare -- bar="7*9"

Here, bar which is an ordinary value holds the string value "7*9", which
happens to be a valid expression in the eyes of the shell's math parser.
When we assigned "bar" to "foo", which has the "-i" flag set, the string
value was fed to the math parser, and "7" and "9" were temporarily
turned into integers, and a multiplication was performed, and then the
resulting number 63 was turned back into a string, and the string "63"
was stored in "foo".

Why people think this is a good idea is utterly beyond me.  I can only
advise you never to use this thing.  It's confusing and dumb.  If you want
to perform arithmetic while assigning a value to a variable, I advise
you to use an *explicit* arithmetic expression:

foo=$(( math stuff here ))

That way you can see what's happening when you read the script, and there
won't be as many surprises.

Bash is full of enough landmines without introducing more.


Reply to: