Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different result from $((++n)) when running bash vs dash

I'm getting different outputs when running the program in bash and dash

#!/bin/sh

echo $SHELL
n=1
a=$((++n))
echo $n

Bash:

$ bash shell_test.sh
2

Dash:

$ dash shell_test.sh
1
like image 391
user2373153 Avatar asked Sep 24 '18 13:09

user2373153


People also ask

What is the difference between bash and dash?

Bash is a full-featured shell for interactive use and is still the default login shell. However, it is much larger and slower to launch and use. On the other hand, the Dash shell is a simplistic modern POSIX-compliant version of the Bourne shell.

Is dash faster than bash?

If you need speed, go definitely with dash, it is much faster than any other shell and about 4x faster than bash.

What are $( and $(( )) in bash?

$(...) is an expression that starts a new subshell, whose expansion is the standard output produced by the commands it runs. This is similar to another command/expression pair in bash : ((...)) is an arithmetic statement, while $((...)) is an arithmetic expression. Follow this answer to receive notifications.

What is the difference between the bash and sh shells?

bash and sh are two different shells of the Unix operating system. bash is sh, but with more features and better syntax. Bash is “Bourne Again SHell”, and is an improvement of the sh (original Bourne shell). Shell scripting is scripting in any shell, whereas Bash scripting is scripting specifically for Bash.


2 Answers

dash is the Debian Almquist shell and an extreme light-weight version of a full POSIX-compliant shell-implementation of /bin/sh that aims to be as small as possible creating faster bootup times.

Operators such as $((n++)), $((--n)) and similar are features that are not required by POSIX and therefore not implemented.

To see how dash interprets these statements, see Chepner's answer

A nice page explaining how to make your script POSIX compliant, is here.


2.6.4 Arithmetic Expansion: Arithmetic expansion provides a mechanism for evaluating an arithmetic expression and substituting its value. The format for arithmetic expansion shall be as follows:

$((expression))

The expression shall be treated as if it were in double-quotes, except that a double-quote inside the expression is not treated specially. The shell shall expand all tokens in the expression for parameter expansion, command substitution, and quote removal.

Next, the shell shall treat this as an arithmetic expression and substitute the value of the expression. The arithmetic expression shall be processed according to the rules given in Arithmetic Precision and Operations, with the following exceptions:

  • Only signed long integer arithmetic is required.
  • Only the decimal-constant, octal-constant, and hexadecimal-constant constants specified in the ISO C standard, Section 6.4.4.1 are required to be recognized as constants.
  • The sizeof() operator and the prefix and postfix ++ and -- operators are not required.
  • Selection, iteration, and jump statements are not supported.

source: POSIX IEEE Std 1003.1-2017

like image 64
kvantour Avatar answered Oct 07 '22 18:10

kvantour


Prefix ++ is not required by POSIX, and dash doesn't implement it. Instead, it's parsed as two unary + operators:

$ n=1
$ echo $((+(+n)))
1
$ echo $((++n))
1
$ echo $n
1
like image 6
chepner Avatar answered Oct 07 '22 17:10

chepner