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

Oliver Fromme olli at
Thu Nov 16 12:06:17 UTC 2006

Tom Rhodes <trhodes at> 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 : .
   $ 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
   $ let 4 \| 3

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
   $ echo $xyz

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, 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

Just my 2 cents.

Best regards

Oliver Fromme,  secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing
Dienstleistungen mit Schwerpunkt FreeBSD:
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