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

comparing strings with < and >

18 views
Skip to first unread message

John Doe

unread,
Jun 13, 2015, 5:20:29 AM6/13/15
to
I learn shell programming and found this behavior:

if ( test "a" > "b" ) then echo t; else echo f; fi
if ( test "a" < "b" ) then echo t; else echo f; fi

Both lines return t(rue). I've read in manual that test requires
arguments with conditional expressions, and under "conditional
expressions" I can see:

string1 < string2
True if string1 sorts before string2 lexicographically.

string1 > string2
True if string1 sorts after string2 lexicographically.

I'm missing something and cannot find the right explanation for "true"
result in both cases. Why both lines return t(rue)? Is the syntax
incorrect or something else to get true/false results?

John

Janis Papanagnou

unread,
Jun 13, 2015, 5:50:11 AM6/13/15
to
You are redirecting the output of test "a" to file "b". Try:

if [[ "a" > "b" ]] ; then echo t; else echo f; fi

or escape the operator:

if test "a" \> "b" then echo t; else echo f; fi


Janis

>
> John

Janis Papanagnou

unread,
Jun 13, 2015, 5:51:47 AM6/13/15
to
Forgot the semicolon:

John Doe

unread,
Jun 13, 2015, 5:58:23 AM6/13/15
to
On 13.06.2015 11:50, Janis Papanagnou wrote:
Thank you!

John

Stephane Chazelas

unread,
Jun 13, 2015, 6:40:09 AM6/13/15
to
2015-06-13 11:50:07 +0200, Janis Papanagnou:
[...]
> You are redirecting the output of test "a" to file "b". Try:
>
> if [[ "a" > "b" ]] ; then echo t; else echo f; fi
>
> or escape the operator:
>
> if test "a" \> "b" then echo t; else echo f; fi
[...]

Note that those two are not necessarily the same.

First ">" is not a standard "test" operator.

In bash, for test, <, > and = do a strcmp() type of comparison
(for instance é would be considerd greater than f), while for
[[]], = uses strcmp()-type comparison and <, > use strcoll()
type comparison (é would be before f if that's how it's defined
in the locale, and you can have values of $a and $b where none
of <,>,= return true).

POSIXly, you'd use expr:

expr "X$a" '<' "X$b"

For expr, strcoll() is used for =,<,> (as long as the arguments
are not recognised as numbers). That means you can have values
of $a and $b that are different but for which expr's = returns
true (if they are defined in the locale as sorting the same).

That's also true of POSIX awk ==,<,> operators (though gawk and
mawk at least are not conformant as their == does strict
equality a la strcmp()).

--
Stephane

Keith Thompson

unread,
Jun 13, 2015, 1:32:56 PM6/13/15
to
John Doe <john.doe@notpresent> writes:
> I learn shell programming and found this behavior:
>
> if ( test "a" > "b" ) then echo t; else echo f; fi
> if ( test "a" < "b" ) then echo t; else echo f; fi

Others have already pointed out the main problem (< and > in this
context are redirection operators, not relational operators).

Another relatively minor point: the parentheses are not necessary,
and are not part of the syntax of the shell's "if" statement.

The condition in an "if" statement is a command, treated as true
if the command succeeded (returned an exit status of 0) and false
if it failed. The "test" command is designed to succeed or fail
in a way that makes it useful as a condition in a shell "if" or
"while" statement. Parentheses are used for grouping; for example:

( echo Line one ; echo Line two ) > two_lines.txt

The commands are executed in a subshell; use { ... } to execute
the commands in the current process.

In this case they're unnecessary (but harmless). But without the
parentheses, you need a semicolon before the "then". The parentheses
are enough to tell the shell that it's reached the end of the
command. That's not clear from the bash documentation, but the
POSIX spec is more explicit.

--
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"
0 new messages