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

[[ "" -lt 5 ]]

23 views
Skip to first unread message

Hongyi Zhao

unread,
May 27, 2015, 4:10:41 AM5/27/15
to
Hi all,

See this:

$ [[ "" -lt 5 ]]
$ echo $?
0

Why?

Regards
--
.: Hongyi Zhao [ hongyi.zhao AT gmail.com ] Free as in Freedom :.

Kusalananda

unread,
May 27, 2015, 4:30:04 AM5/27/15
to
On 2015-05-27, Hongyi Zhao <hongy...@gmail.com> wrote:
> Hi all,
>
> See this:
>
> $ [[ "" -lt 5 ]]
> $ echo $?
> 0
>
> Why?
>
> Regards

Because "" evaluates to zero when used in an arithmetic context?

$ echo $(( "" ))
0


--
:: Andreas Kusalananda Kahari, Uppsala University, Sweden ::
:: a n d r e a s . k a h a r i @ i c m . u u . s e ::

Hongyi Zhao

unread,
May 27, 2015, 4:56:53 AM5/27/15
to
On Wed, 27 May 2015 08:29:59 +0000, Kusalananda wrote:

> $ echo $(( "" ))
> 0

On my box:

$ echo $(( "" ))
bash: "" : syntax error: operand expected (error token is """ ")

Janis Papanagnou

unread,
May 27, 2015, 10:25:52 AM5/27/15
to
On 27.05.2015 10:10, Hongyi Zhao wrote:
> Hi all,
>
> See this:
>
> $ [[ "" -lt 5 ]]
> $ echo $?
> 0
>
> Why?

Why not? - What else are you expecting if comparing _numbers_ with -lt ?

>
> Regards
>

Kenny McCormack

unread,
May 27, 2015, 11:05:14 AM5/27/15
to
In article <mk4k5d$v2$1...@news.m-online.net>,
See this:

$ echo hello
hello
$

Why?

--
BigBusiness types (aka,
Republicans/Conservatives/Independents/Liberatarians/whatevers)
don't hate big government. They *love* big government as a means for
them to get rich, sucking off the public teat. What they don't like is
*democracy* - little people actually having the right to vote and stuff
like that.

Hongyi Zhao

unread,
May 27, 2015, 7:35:19 PM5/27/15
to
On Wed, 27 May 2015 16:25:49 +0200, Janis Papanagnou wrote:

> Why not? - What else are you expecting if comparing _numbers_ with -lt ?

_Empty string_ is not a _number_ at all, so it is not the same type of
thing as any _numbers_. I think, it will be nonsense when comparing it
with a number with the arithmetic operator, instead, I think it should
have sense when using the string comparison operator, i.e., say, ==, !=,
or =.

So, I think, in this case, the `$?' gives the `0' result is an
inexplicable thing.

Hongyi Zhao

unread,
May 27, 2015, 7:37:24 PM5/27/15
to
On Wed, 27 May 2015 15:05:12 +0000, Kenny McCormack wrote:

> See this:
>
> $ echo hello hello $
>
> Why?

Why ``why'' for this case? It is not the same thing as I mentions here.

Janis Papanagnou

unread,
May 27, 2015, 7:47:33 PM5/27/15
to
On 28.05.2015 01:35, Hongyi Zhao wrote:
> On Wed, 27 May 2015 16:25:49 +0200, Janis Papanagnou wrote:
>
>> Why not? - What else are you expecting if comparing _numbers_ with -lt ?
>
> _Empty string_ is not a _number_ at all,

And why do you then use '-lt', an arithmetic comparison with strings?

> so it is not the same type of
> thing as any _numbers_. I think, it will be nonsense when comparing it
> with a number with the arithmetic operator, instead, I think it should
> have sense when using the string comparison operator, i.e., say, ==, !=,
> or =.

So why did you not use string comparison then?

>
> So, I think, in this case, the `$?' gives the `0' result is an
> inexplicable thing.

You still didn't answer my question: "What else are you expecting?",
and: "Why?" (in the sense: "Based on which specification or standard?".

>
> Regards
>

Thomas 'PointedEars' Lahn

unread,
May 27, 2015, 8:56:19 PM5/27/15
to
Hongyi Zhao wrote:

> On Wed, 27 May 2015 16:25:49 +0200, Janis Papanagnou wrote:
>> Why not? - What else are you expecting if comparing _numbers_ with -lt ?
>
> _Empty string_ is not a _number_ at all, so it is not the same type of
> thing as any _numbers_. I think, it will be nonsense when comparing it
> with a number with the arithmetic operator, instead, I think it should
> have sense when using the string comparison operator, i.e., say, ==, !=,
> or =.
>
> So, I think, in this case, the `$?' gives the `0' result is an
> inexplicable thing.

Not at all. It stands to reason that if an operator is not defined for
operands of a type, then either there is an error message or the operand is
silently converted to a suitable type internally (“type conversion” or “type
coercion”).

I would not be too surprised if "" would be converted to 0 with an
arithmetic comparison operator like “-lt”. Of course, whenever a program’s
behavior puzzles you, you can RTFM, STFW, and UTSL to find out the reason
*before you post to the newsgroup*. And any such assumptions can be easily
tested by experimentation beforehand:

$ [[ -1 -lt "" ]]; echo $?
0

$ [[ -1 -gt "" ]]; echo $?
1

$ [[ 0 -eq "" ]]; echo $?
0

This indicates that my assumption is correct, as −1 < 0, −1 ≯ 0, and 0 = 0.

--
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

Hongyi Zhao

unread,
May 27, 2015, 9:08:18 PM5/27/15
to
On Thu, 28 May 2015 02:53:35 +0200, Thomas 'PointedEars' Lahn wrote:

[...]
Thanks a lot.

> This indicates that my assumption is correct, as −1 < 0, −1 ≯ 0, and 0 =
> 0.

How can you input the characters like this: `≯'?

I use pan2 newsreader and don't know how to input characters like that.

Thomas 'PointedEars' Lahn

unread,
May 27, 2015, 10:24:13 PM5/27/15
to
Hongyi Zhao wrote:

> On Thu, 28 May 2015 02:53:35 +0200, Thomas 'PointedEars' Lahn wrote:
> [...]
> Thanks a lot.

You’re welcome.

>> This indicates that my assumption is correct, as −1 < 0, −1 ≯ 0, and 0 =
>> 0.
>
> How can you input the characters like this: `≯'?
>
> I use pan2 newsreader and don't know how to input characters like that.

<OT>
There are applications like gucharmap where you can search for
the character and/or copy it to the clipboard.

I use KNode as newsreader. As for typing special characters directly,
although your newsreader needs to support Unicode for that as well
(as any sensible application should be nowadays), it is not so much
a matter of the newsreader as of the keyboard driver:

I use the standard Xkb of the X.org platform on Debian GNU/Linux, and
this affords me, among other features, the equivalent of a Compose key
using Shift+AltGr (as I configured it using KDE’s “System Settings”;
this only runs xkbcomp) on a “Generic 102-key (Intl) PC” keyboard with
“German (Switzerland)” layout . Then I type “>” and “/” in sequence
to get “≯” (the reverse order also works). Several of those sequences
are predefined, but you can override them and define your own.

In addition, you can modify the keyboard layout. I have defined several
Greek letters, symbols, and constants, e.g. “ℏ” on AltGr+h; if you need
“≯” more often, you could define it on AltGr+Shift+> (similar to the
Mac OS X keyboard layout).
</OT>

In case I look for one or forget a Compose sequence, I have defined

$ alias compose-help
alias compose-help='grep --color /usr/share/X11/locale/en_US.UTF-8/Compose ~/.XCompose -e'

For example:

$ compose-help 'less.*than' -i
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <less> <equal> : "≤" U2264 # LESS-THAN OR EQUAL TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <less> <U0338> : "≮" U226E # NOT LESS-THAN
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <leftcaret> <U0338> : "≮" U226E # NOT LESS-THAN
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <lessthanequal> <U0338> : "≰" U2270 # NEITHER LESS-THAN NOR EQUAL TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <U2272> <U0338> : "≴" U2274 # NEITHER LESS-THAN NOR EQUIVALENT TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <U2276> <U0338> : "≸" U2278 # NEITHER LESS-THAN NOR GREATER-THAN
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <U2277> <U0338> : "≹" U2279 # NEITHER GREATER-THAN NOR LESS-THAN
/usr/share/X11/locale/en_US.UTF-8/Compose:<dead_stroke> <less> : "≮" U226E # NOT LESS-THAN
/usr/share/X11/locale/en_US.UTF-8/Compose:<dead_stroke> <lessthanequal> : "≰" U2270 # NEITHER LESS-THAN NOR EQUAL TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<dead_tilde> <less> : "≲" U2272 # LESS-THAN OR EQUIVALENT TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <less> <underscore> : "≤" U2264 # < _ LESS-THAN OR EQUAL TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <underscore> <less> : "≤" U2264 # _ < LESS-THAN OR EQUAL TO
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <less> <U2395> : "⍃" U2343 # < ⎕ APL FUNCTIONAL SYMBOL QUAD LESS-THAN
/usr/share/X11/locale/en_US.UTF-8/Compose:<Multi_key> <U2395> <less> : "⍃" U2343 # ⎕ < APL FUNCTIONAL SYMBOL QUAD LESS-THAN
/home/****/.XCompose:<Multi_key> <Multi_key> <less> : "≪" U226A # U+226A MUCH LESS THAN

HTH

Keith Thompson

unread,
May 30, 2015, 11:00:25 PM5/30/15
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:
> Hongyi Zhao wrote:
>
>> On Wed, 27 May 2015 16:25:49 +0200, Janis Papanagnou wrote:
>>> Why not? - What else are you expecting if comparing _numbers_ with -lt ?
>>
>> _Empty string_ is not a _number_ at all, so it is not the same type of
>> thing as any _numbers_. I think, it will be nonsense when comparing it
>> with a number with the arithmetic operator, instead, I think it should
>> have sense when using the string comparison operator, i.e., say, ==, !=,
>> or =.
>>
>> So, I think, in this case, the `$?' gives the `0' result is an
>> inexplicable thing.
>
> Not at all. It stands to reason that if an operator is not defined for
> operands of a type, then either there is an error message or the operand is
> silently converted to a suitable type internally (“type conversion” or “type
> coercion”).

In this case, I'd expect an error message rather than a silent
conversion of an empty string to the number 0.

> I would not be too surprised if "" would be converted to 0 with an
> arithmetic comparison operator like “-lt”. Of course, whenever a program’s
> behavior puzzles you, you can RTFM, STFW, and UTSL to find out the reason
> *before you post to the newsgroup*. And any such assumptions can be easily
> tested by experimentation beforehand:

The OP did try it and included the results in his question. He was
asking why it behaves this way, which not something that can be answered
simply by observing the behavior.

I just tried it myself in bash 4.3.11:

$ if [[ "" -lt 5 ]] ; then echo yes ; else echo no ; fi
yes
$ if [ "" -lt 5 ] ; then echo yes ; else echo no ; fi
bash: [: : integer expression expected
no
$

I'm not overly surprised that [ and [[ behave differently, but I see no
particular reason for [ to print an error message while [[ doesn't. The
bash documentation is not illuminating; the section on [[ doesn't
specifically mention numeric comparison. The section on "Bash
Conditional Expressions" says:

Conditional expressions are used by the `[[' compound command and
the `test' and `[' builtin commands.

and later:

`ARG1 OP ARG2'
`OP' is one of `-eq', `-ne', `-lt', `-le', `-gt', or `-ge'.
These arithmetic binary operators return true if ARG1 is equal
to, not equal to, less than, less than or equal to, greater
than, or greater than or equal to ARG2, respectively. ARG1 and
ARG2 may be positive or negative integers.

Based on that, IMHO

[[ "" -lt 5 ]]

*should* produce an error message, though the documentation doesn't
explicitly say so. The fact that it doesn't is probably a bug.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Janis Papanagnou

unread,
May 31, 2015, 1:13:49 AM5/31/15
to
On 31.05.2015 05:00, Keith Thompson wrote:
[...]
>
> I just tried it myself in bash 4.3.11:
>
> $ if [[ "" -lt 5 ]] ; then echo yes ; else echo no ; fi
> yes
> $ if [ "" -lt 5 ] ; then echo yes ; else echo no ; fi
> bash: [: : integer expression expected
> no
> $
>
> I'm not overly surprised that [ and [[ behave differently, but I see no
> particular reason for [ to print an error message while [[ doesn't.

Note that ksh and zsh return no error, and return "yes", in both cases.

And the ksh man page also points out that those tests and operators are
"obsolete arithmetic comparisons"; given that we have $((...)) expansion
even in the standard, and the ((...)) command supported by the prominent
shells.

It's anyway beyond me why anyone would for one use a _contemporary_ (but
non-standard) test syntax [[...]], but use the _ancient_ (and obsolete)
-lt, -le, -eq, etc. operators.

Janis

> [...]

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 12:09:37 PM5/31/15
to
Keith Thompson wrote:

> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>> Hongyi Zhao wrote:
>>> On Wed, 27 May 2015 16:25:49 +0200, Janis Papanagnou wrote:
>>>> Why not? - What else are you expecting if comparing _numbers_ with -lt
>>>> ?
>>> _Empty string_ is not a _number_ at all, so it is not the same type of
>>> thing as any _numbers_. I think, it will be nonsense when comparing it
>>> with a number with the arithmetic operator, instead, I think it should
>>> have sense when using the string comparison operator, i.e., say, ==, !=,
>>> or =.
>>> So, I think, in this case, the `$?' gives the `0' result is an
>>> inexplicable thing.
>> Not at all. It stands to reason that if an operator is not defined for
>> operands of a type, then either there is an error message or the operand
>> is silently converted to a suitable type internally (“type conversion” or
>> “type coercion”).
>
> In this case, I'd expect an error message rather than a silent
> conversion of an empty string to the number 0.

On which grounds?

>> I would not be too surprised if "" would be converted to 0 with an
>> arithmetic comparison operator like “-lt”. Of course, whenever a
>> program’s behavior puzzles you, you can RTFM, STFW, and UTSL to find out
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> the reason *before you post to the newsgroup*. And any such assumptions
>> can be easily tested by experimentation beforehand:
>
> The OP did try it and included the results in his question. He was
> asking why it behaves this way, which not something that can be answered
> simply by observing the behavior.

I have marked the relevant parts for you.

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 12:13:58 PM5/31/15
to
Janis Papanagnou wrote:

> It's anyway beyond me why anyone would for one use a _contemporary_ (but
> non-standard) test syntax [[...]], but use the _ancient_ (and obsolete)
> -lt, -le, -eq, etc. operators.

Why do you think those arithmetic operators would be obsolete?

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 12:37:39 PM5/31/15
to
Keith Thompson wrote:

> I just tried it myself in bash 4.3.11:
>
> $ if [[ "" -lt 5 ]] ; then echo yes ; else echo no ; fi
> yes
> $ if [ "" -lt 5 ] ; then echo yes ; else echo no ; fi
> bash: [: : integer expression expected
> no
> $
>
> I'm not overly surprised that [ and [[ behave differently, but I see no
> particular reason for [ to print an error message while [[ doesn't.

ISTM to be obvious: “[[ … ]]” does type conversion; “[ … ]”, equivalent to
“test”, does not. This probably has to do with backwards compatibility; “[[
… ]]” is a *non-standard* feature that is a *compound* command –

| Compound Commands
|
| […]
|
| [[ expression ]]
| Return a status of 0 or 1 depending on the evaluation of the
| conditional expression expression. Expressions are
| composed of the primaries described below under
| CONDITIONAL EXPRESSIONS. Word splitting and pathname
| expansion are not performed on the words between the [[ and
| ]]; tilde expansion, parameter and variable expansion,
| arithmetic expansion, command substitution, process sub‐
| stitution, and quote removal are performed. Conditional
| operators such as -f must be unquoted to be recognized as
| primaries.
|
| When used with [[, the < and > operators sort
| lexicographically using the current locale.

– while “[”, respectively “test”, is a *standard* feature that is a *simple*
built-in command:

| SHELL BUILTIN COMMANDS
|
| […]
|
| test expr
| [ expr ]
| Return a status of 0 (true) or 1 (false) depending on the
| evaluation of the conditional expression expr. Each
| operator and operand must be a separate argument.
| Expressions are composed of the primaries described above
| under CONDITIONAL EXPRESSIONS. test does
| not accept any options, nor does it accept and ignore an
| argument of -- as signifying the end of options.
|
| test and [ evaluate conditional expressions using a set of
| rules based on the number of arguments.
|
| […]
| 3 arguments
| The following conditions are applied in the order
| listed. If the second argument is one of the binary
| conditional operators listed above under
| CONDITIONAL EXPRESSIONS, the result of the expression
| is the result of the binary test using the first
| and third arguments as operands. The -a and -o
| operators are considered binary operators when there
| are three arguments.
| If the first argument is !, the value is the negation
| of the two-argument test using the second and third
| arguments. If the first argument is exactly ( and
| the third argument is exactly ), the result is the
| one-argument test of the second argument.
| Otherwise, the expression is false.
`----

See also:
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html>

> The bash documentation is not illuminating; the section on [[ doesn't
> specifically mention numeric comparison.

True.

> […] IMHO
>
> [[ "" -lt 5 ]]
>
> *should* produce an error message, though the documentation doesn't
> explicitly say so. The fact that it doesn't is probably a bug.

It is a *documentation* bug that it the documentation does not say that no
error message is produced, and that type conversion is performed instead.

Janis Papanagnou

unread,
May 31, 2015, 12:40:11 PM5/31/15
to
On 31.05.2015 18:11, Thomas 'PointedEars' Lahn wrote:
> Janis Papanagnou wrote:
>
>> It's anyway beyond me why anyone would for one use a _contemporary_ (but
>> non-standard) test syntax [[...]], but use the _ancient_ (and obsolete)
>> -lt, -le, -eq, etc. operators.
>
> Why do you think those arithmetic operators would be obsolete?

Actually, as mentioned in my posting, that was even a quote from the korn
shell manual; but I certainly second it.

In contemporary shells (including POSIX) you have the arithmetic expansion
and arithmetic command that make it possible to formulate legible numeric
expressions and without quirks.

Just to not be misunderstood; the shells (of course) still needs to support
those operators to run old scripts. But the ancient operators are obsolete
for the programmers to be used in shell programs if they write new code.

Janis

Janis Papanagnou

unread,
May 31, 2015, 12:43:58 PM5/31/15
to
On 31.05.2015 18:40, Janis Papanagnou wrote:
[...]
>
> In contemporary shells (including POSIX) you have the arithmetic expansion
> and arithmetic command that make it possible to formulate legible numeric
> expressions and without quirks.

Wrong formulation; should have been:

In contemporary shells you have the arithmetic expansion (included in POSIX)
and the arithmetic command that make it possible to formulate legible numeric
expressions and without quirks.

> [...]
>
> Janis
>

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 1:22:05 PM5/31/15
to
Interesting. How do you suggest I replace

x=1

# $x is unknown here
if [ "$x" -lt 3 ]; then
foo
fi

and

# $y is unknown here
if [[ $y -lt 3 ]]; then
bar
fi

using arithmetic expansion?

Janis Papanagnou

unread,
May 31, 2015, 2:14:18 PM5/31/15
to
With ksh, zsh, bash, I'd do

if (( y < 3 ))


Janis

>

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 3:50:22 PM5/31/15
to
This works, but it is the non-standard [1] compound command “(( … ))”, using
arithmetic _evaluation_:

,-[bash(1)
|
| Compound Commands
| […]
| ((expression))
| The expression is evaluated according to the rules
| described below under ARITHMETIC EVALUATION. If the value
| of the expression is non-zero, the return status is 0;
| otherwise the return status is 1. This is exactly
| equivalent to `let "expression"'.

Standard (POSIX:2008) arithmetic *expansion* is done on “$(( … ))” instead,
where with arithmetic comparison operators the expression is replaced by 0
if the condition is false, and 1 if it is true. [2] (In my tests in bash
4.3.33(1)-release on Debian GNU/Linux sid/stretch, the exit status is always
0.)

ISTM that using arithmetic *expansion* you would need another variable and
another comparison, so that is not better than the *standard* arithmetic
comparison operators [3] that the ksh manual and you call “obsolete”. They
do not appear to be obsolete in *portable* shell scripts (which is probably
why have not seen much of “(( … ))” in system scripts).

[1]
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04>
[2]
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04>
[3] <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html>

Janis Papanagnou

unread,
May 31, 2015, 6:11:32 PM5/31/15
to
On 31.05.2015 21:47, Thomas 'PointedEars' Lahn wrote:
> Janis Papanagnou wrote:
>
>> On 31.05.2015 19:19, Thomas 'PointedEars' Lahn wrote:
>>> Interesting. How do you suggest I replace
>>>
>>> x=1
>>>
>>> # $x is unknown here
>>> if [ "$x" -lt 3 ]; then
>>> foo
>>> fi
>>>
>>> and
>>>
>>> # $y is unknown here
>>> if [[ $y -lt 3 ]]; then
>>> bar
>>> fi
>>>
>>> using arithmetic expansion?
>>
>> With ksh, zsh, bash, I'd do
>>
>> if (( y < 3 ))
>
> This works, but it is the non-standard [1] compound command “(( … ))”, using
> arithmetic _evaluation_:

Yes. That's why I wrote: ksh, zsh, bash.

(Note, if you restrict yourself to POSIX then you can also not use "[[...]]"
as you've done above in one of the two samples.)

>
> [...]
>
> ISTM that using arithmetic *expansion* you would need another variable and

Yes. (And I would certainly not do that in this form.)

Janis

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 6:37:49 PM5/31/15
to
Janis Papanagnou wrote:

> On 31.05.2015 21:47, Thomas 'PointedEars' Lahn wrote:
>> Janis Papanagnou wrote:
>>> On 31.05.2015 19:19, Thomas 'PointedEars' Lahn wrote:
>>>> Interesting. How do you suggest I replace
>>>>
>>>> x=1
>>>>
>>>> # $x is unknown here
>>>> if [ "$x" -lt 3 ]; then
>>>> foo
>>>> fi
>>>>
>>>> and
>>>>
>>>> # $y is unknown here
>>>> if [[ $y -lt 3 ]]; then
>>>> bar
>>>> fi
>>>>
>>>> using arithmetic expansion?
>>>
>>> With ksh, zsh, bash, I'd do
>>>
>>> if (( y < 3 ))
>>
>> This works, but it is the non-standard [1] compound command “(( … ))”,
>> using arithmetic _evaluation_:
>
> Yes. That's why I wrote: ksh, zsh, bash.

My point, which you have missed, is that the compound command using
arithmetic evaluation is *different* from arithmetic expansion. The former
is _not_ standard-compliant, the latter is. You said:

| And the ksh man page also points out that those tests and operators are
| "obsolete arithmetic comparisons"; given that we have $((...)) expansion
| even in the standard, and the ((...)) command supported by the prominent
| shells.

It is a fallacious argument of you to say that “(( … ))” is supported by
“the prominent shells” in combination with the (correct) statement that
“we have $(( … )) expansion even in the standard”. Those are *separate*
features and they work *differently*.

> (Note, if you restrict yourself to POSIX then you can also not use
> "[[...]]" as you've done above in one of the two samples.)

True, however the fact that there are shells where the compound command is
not supported is contradictory to the claim that standards-compliant
alternatives would be obsolete. They are obsolete only in the shells in
which the proprietary expression is supported.

Janis Papanagnou

unread,
May 31, 2015, 7:05:18 PM5/31/15
to
On 01.06.2015 00:35, Thomas 'PointedEars' Lahn wrote:
> Janis Papanagnou wrote:
>
>> On 31.05.2015 21:47, Thomas 'PointedEars' Lahn wrote:
>>> Janis Papanagnou wrote:
>>>> On 31.05.2015 19:19, Thomas 'PointedEars' Lahn wrote:
>>>>> Interesting. How do you suggest I replace
>>>>>
>>>>> x=1
>>>>>
>>>>> # $x is unknown here
>>>>> if [ "$x" -lt 3 ]; then
>>>>> foo
>>>>> fi
>>>>>
>>>>> and
>>>>>
>>>>> # $y is unknown here
>>>>> if [[ $y -lt 3 ]]; then
>>>>> bar
>>>>> fi
>>>>>
>>>>> using arithmetic expansion?
>>>>
>>>> With ksh, zsh, bash, I'd do
>>>>
>>>> if (( y < 3 ))
>>>
>>> This works, but it is the non-standard [1] compound command “(( … ))”,
>>> using arithmetic _evaluation_:
>>
>> Yes. That's why I wrote: ksh, zsh, bash.
>
> My point, which you have missed, is that the compound command using
> arithmetic evaluation is *different* from arithmetic expansion.

Of course it is different. I wrote: "In contemporary shells you have the
arithmetic expansion (included in POSIX) and the arithmetic command [...]",
clearly differciating the two.

> The former is _not_ standard-compliant, the latter is.

Yes, as I wrote upthread.

> You said:
>
> | And the ksh man page also points out that those tests and operators are
> | "obsolete arithmetic comparisons"; given that we have $((...)) expansion
> | even in the standard, and the ((...)) command supported by the prominent
> | shells.
>
> It is a fallacious argument of you to say that “(( … ))” is supported by
> “the prominent shells” in combination with the (correct) statement that
> “we have $(( … )) expansion even in the standard”. Those are *separate*
> features and they work *differently*.

As they are different constructs they of course work differently; the one
calculates the expression and returns a sensible exit code the other one
expands its result for use in variables, to print it, etc. The actual
arithmetic features of the two, though, I expect to work exactly the same.

>
>> (Note, if you restrict yourself to POSIX then you can also not use
>> "[[...]]" as you've done above in one of the two samples.)
>
> True, however the fact that there are shells where the compound command is
> not supported is contradictory to the claim that standards-compliant
> alternatives would be obsolete. They are obsolete only in the shells in
> which the proprietary expression is supported.

Exactly. And now re-read the source of all that (IMO hair splitting) in one
of my first postings of this subthread (expressis verbis):

>> It's anyway beyond me why anyone would for one use a _contemporary_ (but
>> non-standard) test syntax [[...]], but use the _ancient_ (and obsolete)
>> -lt, -le, -eq, etc. operators.

I think it should have been quite clear in which context the obsolescence
has to be seen. YMMV.

Janis

Thomas 'PointedEars' Lahn

unread,
May 31, 2015, 7:25:50 PM5/31/15
to
Janis Papanagnou wrote:

> On 01.06.2015 00:35, Thomas 'PointedEars' Lahn wrote:
>> You said:
>>
>> | And the ksh man page also points out that those tests and operators
>> | are "obsolete arithmetic comparisons"; given that we have $((...))
>> | expansion even in the standard, and the ((...)) command supported by
>> | the prominent shells.
>>
>> It is a fallacious argument of you to say that “(( … ))” is supported by
>> “the prominent shells” in combination with the (correct) statement that
>> “we have $(( … )) expansion even in the standard”. Those are *separate*
>> features and they work *differently*.
>
> As they are different constructs they of course work differently; the one
> calculates the expression and returns a sensible exit code the other one
> expands its result for use in variables, to print it, etc. The actual
> arithmetic features of the two, though, I expect to work exactly the same.

Apparently I am not making myself clear. Let me try again: It is complete,
utter nonsense of you to claim that it would be better to use “(( … ))” on
the grounds that “$(( … ))” is in the standard. “(( … ))” *has nothing to
do* with “$(( … ))”.

Janis Papanagnou

unread,
May 31, 2015, 11:38:36 PM5/31/15
to
No one said what you claim here to have been said! - I suggest to stop that,
and re-read what I wrote instead of repeating to allege this utter nonsense.

My last try is a requote and final explanation. I wrote in above respect:

>> And the ksh man page also points out that those tests and operators are
>> "obsolete arithmetic comparisons"; given that we have $((...)) expansion
>> even in the standard, and the ((...)) command supported by the prominent
>> shells.

Note the syntactical grouping that specifies the semantics:
"$((...)) expansion even in the standard,"
"and the ((...)) command supported by the prominent shells."

You can simply ignore - if you like - my mentioning of one being standard and
the other not, despite you mentioned it afterwards yourself (while not adding
anything new). The point is that this all is used (based on the OP's code) in
context of the *non-standard* "[[...]]".

tl;dr
If you don't care about being POSIX complient you can use [[...]] or ((...));
if in that case you want to do arithmetic don't use [[...]] but ((...)), and
avoid the obsolete arithmetic operator to obtain legible code.

Janis

Hongyi Zhao

unread,
Jun 1, 2015, 8:36:15 AM6/1/15
to
On Sun, 31 May 2015 18:34:57 +0200, Thomas 'PointedEars' Lahn wrote:

> ISTM to be obvious: “[[ … ]]” does type conversion; “[ … ]”,

How to input … here instead of ... ? Do you do it by using some pre-
defined macros for this within in your newsreader?

Thomas 'PointedEars' Lahn

unread,
Jun 6, 2015, 4:39:02 AM6/6/15
to
Janis Papanagnou wrote:

> On 01.06.2015 01:23, Thomas 'PointedEars' Lahn wrote:
>> Janis Papanagnou wrote:
>>> And the ksh man page also points out that those tests and operators are
>>> "obsolete arithmetic comparisons"; given that we have $((...)) expansion
>>> even in the standard, and the ((...)) command supported by the prominent
>>> shells.
>
> Note the syntactical grouping that specifies the semantics:
> "$((...)) expansion even in the standard,"

is completely irrelevant with respect to “(( … ))” vs. “[[ … ]]” or “[ … ]”.

> "and the ((...)) command supported by the prominent shells."
>
> You can simply ignore - if you like - my mentioning of one being standard
> and the other not, […]

I do not ignore it. But your comment regarding the standard-compliance of
“$(( … ))” is *irrelevant*, and the “given” and “even” there look
suspicious, if not fallacious *in this context*. It sure looks as if you
would *justify* the use of the latter by the fact of the former.

But just because two features have similar *syntax* (the two here only
differ by the “$” prefix) that does _not_ mean that one can be or should be
a reason for using the other.

*That* is *my* point that *you* are ignoring.

Thomas 'PointedEars' Lahn

unread,
Jun 6, 2015, 4:52:16 AM6/6/15
to
Hongyi Zhao wrote:

> On Sun, 31 May 2015 18:34:57 +0200, Thomas 'PointedEars' Lahn wrote:
>> ISTM to be obvious: “[[ … ]]” does type conversion; “[ … ]”,
>
> How to input … here instead of ... ? Do you do it by using some pre-
> defined macros for this within in your newsreader?

See <news:2395987.l...@PointedEars.de>.

Questions that are completely off-topic should be sent as e-mail or the
discussion should be redirected by crosspost (X-Post) and Followup-To
(F'up2) to the appropriate newsgroup; in this case, probably
<news:comp.os.linux.x>.

Janis Papanagnou

unread,
Jun 6, 2015, 6:57:42 AM6/6/15
to
On 06.06.2015 10:36, Thomas 'PointedEars' Lahn wrote:
[snip]
>
> [...] It sure looks as if [...]

That says it all. Now please stop that nonsense, and get a life.

Keith Thompson

unread,
Jun 7, 2015, 10:50:32 PM6/7/15
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:
> Keith Thompson wrote:
>> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>>> Hongyi Zhao wrote:
>>>> On Wed, 27 May 2015 16:25:49 +0200, Janis Papanagnou wrote:
>>>>> Why not? - What else are you expecting if comparing _numbers_ with -lt
>>>>> ?
>>>> _Empty string_ is not a _number_ at all, so it is not the same type of
>>>> thing as any _numbers_. I think, it will be nonsense when comparing it
>>>> with a number with the arithmetic operator, instead, I think it should
>>>> have sense when using the string comparison operator, i.e., say, ==, !=,
>>>> or =.
>>>> So, I think, in this case, the `$?' gives the `0' result is an
>>>> inexplicable thing.
>>> Not at all. It stands to reason that if an operator is not defined for
>>> operands of a type, then either there is an error message or the operand
>>> is silently converted to a suitable type internally (“type conversion” or
>>> “type coercion”).
>>
>> In this case, I'd expect an error message rather than a silent
>> conversion of an empty string to the number 0.
>
> On which grounds?

On the grounds that, as the bash manual says, the two operands of "-lt"
operator "may be positive or negative integers". (Presumably the
omission of zero was an oversight.) "" is not a positive or negative
integer -- or am I mistaken on that point? I see no explicit statement
that it should produce an error message, but I would expect such an
error to be diagnosed.

>>> I would not be too surprised if "" would be converted to 0 with an
>>> arithmetic comparison operator like “-lt”. Of course, whenever a
>>> program’s behavior puzzles you, you can RTFM, STFW, and UTSL to find out
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> the reason *before you post to the newsgroup*. And any such assumptions
>>> can be easily tested by experimentation beforehand:
>>
>> The OP did try it and included the results in his question. He was
>> asking why it behaves this way, which not something that can be answered
>> simply by observing the behavior.
>
> I have marked the relevant parts for you.

Thank you, I already read them. TFM does not, as far as I can tell,
answer the OP's question, which was *why*

[[ "" -lt 5 ]]

is not treated as an error. TFW is no more helpful as far as I can tell
(search for punctuation can be difficult). I'm not sure that TSL would
be helpful; an understanding of the source might verify the observed
behavior, but it wouldn't necessarily

Do you know why that expression doesn't produce an error message? Is
there some standard or documentation that leads you to believe that ""
should be treated as a numeric 0 in that context?

Thomas 'PointedEars' Lahn

unread,
Jun 14, 2015, 3:59:11 PM6/14/15
to
Keith Thompson wrote:

> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>> Keith Thompson wrote:
>>> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>>>>> So, I think, in this case, the `$?' gives the `0' result is an
>>>>> inexplicable thing.
>>>> Not at all. It stands to reason that if an operator is not defined for
>>>> operands of a type, then either there is an error message or the
>>>> operand is silently converted to a suitable type internally (“type
>>>> conversion” or “type coercion”).
>>> In this case, I'd expect an error message rather than a silent
>>> conversion of an empty string to the number 0.
>> On which grounds?
>
> On the grounds that, as the bash manual says, the two operands of "-lt"
> operator "may be positive or negative integers".

Insufficient.

> (Presumably the omission of zero was an oversight.)

There is a convention foreign to mathematics, but prevalent in computer
science and technology, that says positive numbers are those without
negative sign (where the sign bit of the number storage is not set, or
zero). According to that convention positive zero (+0) is included in the
set of positive integers, whereas negative zero (−0) is included in the set
of negative integers.

> "" is not a positive or negative integer -- or am I mistaken on that
> point?

It is not. Which is why type conversion is necessary for *arithmetic*
evaluation to be successful.

> I see no explicit statement that it should produce an error message,
> but I would expect such an error to be diagnosed.

That is *your* expectation. It would appear that the authors of Bash found
it more useful that whenever an arithmetic expression could not be evaluated
the operands would be converted to make that possible, instead of failing.
That appears to have to do with the fact that Bash still supports the POSIX
“test” command and its “[ … ]” shortcut for cases where you do not
necessarily want to evaluate the test expression arithmetically.

>>>> I would not be too surprised if "" would be converted to 0 with an
>>>> arithmetic comparison operator like “-lt”. Of course, whenever a
>>>> program’s behavior puzzles you, you can RTFM, STFW, and UTSL to find
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> out the reason *before you post to the newsgroup*. And any such
>>>> assumptions can be easily tested by experimentation beforehand:
>>>
>>> The OP did try it and included the results in his question.

As I have showed by my tests, their tests were insufficient.

>>> He was asking why it behaves this way, which not something that can be
>>> answered simply by observing the behavior.
>> I have marked the relevant parts for you.
>
> Thank you, I already read them. TFM does not, as far as I can tell,
> answer the OP's question, […]

But UTSL would have. GNU Bash is free software.

> Do you know why that expression doesn't produce an error message?

I have a fairly good idea as to the reason now.

> Is there some standard or documentation that leads you to believe that ""
> should be treated as a numeric 0 in that context?

Yes.

I have also done tests whose results I posted before. Those results
strictly lead to the conclusion that this does occur. Add to that
what the Bash source code appears to be saying.
0 new messages