1

In Bash and Posix shells, there are many forms of commands, and an assignment is a form of command (specifically a simple command) if I am correct.

However let can be used in front of an assignment, and let is supposed to be used in front of an expression. So an assignment is also an expression, if I am correct.

What differences are between an assignment with and without let in front of it, both used as commands? I am asking mainly about differences between their purposes, i.e. when to use which. For example

$ aaa=1

$ let aaa=1
Tim
  • 101,790

4 Answers4

3

As far as I know, let is not POSIX compatible. ShellCheck agrees:

$ cat test.sh
#!/bin/sh
let a=3

$ shellcheck test.sh
In test.sh line 2:
let a=3
^-- SC2039: In POSIX sh, 'let' is undefined.

The bash man page says:

((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".

and

ARITHMETIC EVALUATION

The shell allows arithmetic expressions to be evaluated, under certain circumstances (see the let and declare builtin commands and Arithmetic Expansion). Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error. The operators and their precedence, associativity, and values are the same as in the C language. The following list of operators is grouped into levels of equal-precedence operators. The levels are listed in order of decreasing precedence.

= *= /= %= += -= <<= >>= &= ^= |= assignment

and

let arg [arg ...] Each arg is an arithmetic expression to be evaluated (see ARITHMETIC EVALUATION above). If the last arg evaluates to 0, let returns 1; 0 is returned otherwise.

So, in bash an assignment is also an expression and since you can evaluate one ore more expressions with let, you can do one ore more assignments with a single let. But, as noted above, it will not be POSIX compliant.

johnLate
  • 3,034
3

let <EXPRESSION>, while not POSIX-compliant itself, can be expressed in a POSIX conforming way as

[ "$(( <EXPRESSION> ))" -ne 0 ]

As opposed to the plain assignment, let also evaluates the assignment (expression) and returns an exit code depending on the result:

$ aaa=1; echo $?
0
$ aaa=0; echo $?
0

$ let aaa=1; echo $?
0
$ let aaa=0; echo $?
1
Guido
  • 4,114
2

This is documented in the documentation of let, right below where it says it takes an expression.

let expression [expression …]

The let builtin allows arithmetic to be performed on shell variables. Each expression is evaluated according to the rules given below in Shell Arithmetic. If the last expression evaluates to 0, let returns 1; otherwise 0 is returned.

Shell arithmetic includes assignment operators =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, and |=. This is not, in general, related to ordinary assignment statements, which do not apply any additional processing.

Michael Homer
  • 76,565
0

Variable assignments are neither an expression or command, they are part of the "simple command" syntax. Assignments can appear before a command word and modify the environment of that command. If assignments appear without a command they modify the current shell's environment instead.

See: https://www.gnu.org/software/bash/manual/html_node/Simple-Command-Expansion.html

See also this answer: What is this shell/Bash syntax: someVariable=someValue someCommand

let is a Bash built-in command that implements it's own syntax and assignment operators, as @Michael Homer points out. help let provides a handy reference.

remcycles
  • 101