From: Stephane CHAZELAS on
2008-06-15, 06:48(+00), Wolfgang Meister:
> As I learned it is not always necessary to use `expr ....` (with backticks) to
> calculate mathematical expressions. When I do for example the following
>
> firstsec=345
> secondsec=723
> diffsec=$((secondsec - firstsec))
> echo diff=$diffsec
>
> then it works although I did not used "expr" for calculate the difference.
>
> So when do I have to use expr and when not?
[...]

You need expr in that case when writing scripts meant to be
portable to systems that don't have a POSIX shell. Mostly more
than 15 year old systems I'd say, or embedded systems that come
with a torn down version of a shell.

The Bourne shell and early versions of the Almquist shell didn't
have $((...)). In modern Unices, sh is no longer a Bourne shell
but an interpreter or the other of a standard sh language
specified by POSIX. And that language has $((...)).

The ":" operator of "expr" can still be uselful nowadays.

You may still want to use expr when dealing with 0 padded
decimal numbers. For $((...)), 010 is 8 (octal 010) while for
expr, it's 10.

--
St�phane
From: Stephane CHAZELAS on
2008-06-15, 14:38(-04), Wayne:
[...]
>> The ":" operator of "expr" can still be uselful nowadays.
>
> Indeed, expr can be used with if to test if some value is
> a number, something that test alone can't do. And while
> sed can be used to return a testable value when matching
> some string against a regular expression, it is much
> easier with expr.

Yes, and sed operates on lines by default, while expr operates
on a string that may contain several lines.

expr can also be used for string comparison.

expr "x$string1" "<" "x$string2"

which the POSIX "[" can't do.

>> You may still want to use expr when dealing with 0 padded
>> decimal numbers. For $((...)), 010 is 8 (octal 010) while for
>> expr, it's 10.
>
> Of course you can also easily strip off leading zeros from
> numbers in shell variables in POSIX shells, using ${NUM##0}:
> $(( ${aaa##0} - ${bbb##0} ))
[...]

The problem with that is that it strips only one 0, and for the
number "0" itself, it converts it to an empty string.

${aaa#"${aaa%%[!0]*}"}

removes every leading 0, but doesn't solve the other problem and
becomes hard to read. You'd probably want to use a function to
do the 0 stripping.

strip_zeros() {
eval "$1=\${$1#\"\${$1%%[!0]*}\"}; $1=\${$1:-0}"
}
strip_zeros aaa

for instance.

--
St�phane