sh(1) still has support for "let" keyword

Oliver Fromme olli at lurza.secnetix.de
Thu Nov 16 12:06:17 UTC 2006


Tom Rhodes <trhodes at freebsd.org> wrote:
 > PR: 104432 discusses the keyword let, which seems to be nothing
 > more than an alias for expr and works just like it.

Not exactly.  It supports numeric arithmetics, but not the
other features of expr(1), e.g. regular expression matching:

   $ expr foo : .
   1
   $ let foo : .
   let: arith: syntax error: "foo : ."

There are also some incompatibilities:  "|" and "&" are
boolean operators in expr, but binary operators in let:

   $ expr 4 \| 3
   4
   $ let 4 \| 3
   7

Also, the "let" builtin can be used to assign the result
to a variable (it is still also printed to stdout):

   $ let xyz = 6 \* 7
   42
   $ echo $xyz
   42

On the other hand, the "let" builtin is completely redundant
because all of the above can also be done with arithmetic
expansion via $((...)), which is POSIX-compliant.

 > It appears
 > to have been around since FreeBSD 2.2.  At one point, this was
 > documented in the manual pages, originally it was documented in
 > revision 1.9.2.10, RELENG_2_2.  That revision was a stable branch
 > at the time and perhaps, when RELENG_3 was branched, the changes
 > were not picked up.
 > 
 > I was thinking of removing it, but discussions pushed me to
 > consider placing it under #ifndef _POSIX_SOURCE, kind of like
 > how ed(1) has.  Questions/comments?

Personally I would prefer such an #ifndef, too.  There
might be a few scripts out there using "let", so it would
be a good thing not to break them.  (Some authors of
scripts might have used "let" instead of expr(1) because
of efficiency reasons, since the former is built-in and
doesn't require the fork/exec overhead.  It's also worth
noting that very old versions of the shell didn't support
arithmetic expansion via $((...)), so authors might have
used "let" instead.)

Another thing to note is that "let" is a builtin of most
other bourne shells (I just checked zsh, bash and pdksh),
which might be another reason to keep it in our sh, too.
However, "let" works a bit different in those three
shells:  The result is _never_ echoed to stdour (only the
assignments take place), and white space between operands
and operators is not allowed:

   $ zsh        # bash and pdksh are exactly the same
   $ let a = 3 + 4
   zsh: bad math expression: operand expected at `='
   $ let a=3+4
   $ echo $a
   7

Just my 2 cents.

Best regards
   Oliver

-- 
Oliver Fromme,  secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing
Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd
Any opinions expressed in this message may be personal to the author
and may not necessarily reflect the opinions of secnetix in any way.

We're sysadmins.  To us, data is a protocol-overhead.


More information about the freebsd-standards mailing list