1. Overview

What is a shell? In any Linux system, a shell is an interface to process user input by executing the relevant commands and displaying the output to the user. In simple terms, a shell is an environment to perform tasks via the command-line interface. There are mainly two types of shells in Linux: the Bourne shell and the C shell. The Bourne shell has many subcategories:

  • POSIX shell (sh)
  • Bourne shell (sh)
  • Korn shell (ksh)
  • Bourne Again shell (bash)
  • Z shell (zsh)
  • Debian Almquist shell (dash)

In this article, let’s dive into two particular shells: Bash and Dash.

2. Key Differences Between Dash and Bash

Bash has been the default standard interactive shell in most Linux distributions for a long time. However, from Ubuntu 6.10 onwards, Dash replaced Bash. Efficiency was the main reason to change the default shell.

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. Dash has several feature advantages:

  • Consumes minimal disk space, yet it’s feature-rich
  • Low dependence on shared libraries
  • Relatively low boot time
  • Better execution speed

Though the Bash shell is more versatile, extensive, and preferred for user-interactive sessions, the mentioned features of Dash outweigh Bash in terms of speed. In the following sections, let’s compare the performance of both shells.

3. Start-up Time Benchmark Testing

Simple benchmark tests consist of executing a set of commands for a fixed iteration and calculating the time consumption for the whole process. Both shells of interest will undergo the same testing with time consumption measuring their relative performance.

*The start-up time benchmark is a simple test with the “no-operation” (no-op, :) command*. We start the shell in each iteration and do nothing with no-op. The total time consumed will indicate the start-up time for each shell as there are no extra operations performed.

Firstly, let’s see the start-up time test for Bash:

$ cat bash_benchmark_script 
#!/bin/bash
for i in $(seq 1 1000);
do bash -c ":" ;
done
$ time bash bash_benchmark_script 
real    0m1.486s
user    0m1.152s
sys    0m0.327s

Here we have used the time utility to find out the time taken to execute the given script. The bash_benchmark_script tries to invoke the Bash shell to run no-op for 1000 iterations. This means that it takes 1.48sec just to start up the Bash shell 1000 times.

Secondly, let’s check the start-up time test for Dash:

$ cat dash_benchmark_script 
#!/bin/dash
for i in $(seq 1 1000);
do dash -c ":" ;
done
$ time dash dash_benchmark_script 
real    0m0.999s
user    0m0.819s
sys    0m0.134s

The dash_benchmark_script tries to invoke the Dash shell to do no-op for 1000 iterations. This means that it takes just 0.9sec to start up the Dash shell 1000 times.

In short, we see that the start-up time of the Dash shell is about a third less than that of the Bash shell. This efficiency is due to the lower dependency on the shared libraries and smaller total size of Dash in comparison with Bash.

Now that we compared the start-up timing, let’s dive deep into real-time compute performance comparison in the following section.

4. The Shellbench Testing

Shellbench is a benchmark utility for POSIX shell comparison. The shellbench utility runs any given set of commands in an infinite loop for about a second. Then, it returns the number of executions per second, using which the relative performance of the scripting shell is calculated. Consequently, a higher number of executions per second implies better performance.

Furthermore, the utility provides eight sample benchmark tests to check performance with different operations. Actually, we can run tests on several shells like sh, bash, ksh, zsh, and dash at the same time to compare performance.

Now, let’s use the shellbench utility to compare the performance between Bash and Dash:

$ ./shellbench -s bash,dash sample/*
----------------------------------------------------
name                                 bash       dash
----------------------------------------------------
assign.sh: positional params      354,961  1,552,364 
assign.sh: variable               486,657  1,826,733 
assign.sh: local var              505,224  1,888,458 
cmp.sh: [ ]                       254,506    903,775 
cmp.sh: case                      487,977  1,984,710 
count.sh: posix                   394,556  1,219,866 
eval.sh: direct assign            265,855  1,219,592 
eval.sh: eval assign              127,999    780,953 
eval.sh: command subs               2,171      4,932 
func.sh: no func                  471,705  1,964,937 
func.sh: func                     273,133  1,563,748 
null.sh: assign variable          545,798  1,858,063 
null.sh: define function          591,780  2,189,993 
null.sh: undefined variable       440,758  1,943,129 
null.sh: : command                501,115  1,946,933 
output.sh: echo                   331,422  1,020,727 
output.sh: printf                 318,519    999,600 
subshell.sh: no subshell          488,495  1,966,461 
subshell.sh: brace                454,453  1,920,703 
subshell.sh: subshell               2,586      5,206 
subshell.sh: command subs           2,234      4,963 
subshell.sh: external command       1,037      1,083 
----------------------------------------------------
* count: number of executions per second 

Note that we specified the shells of interest (bash,dash) via the -s switch. The main argument to shellbench consists of scripts to run for benchmarking. Here, we used the sample scripts that come with Shellbench itself.

In addition, we can see a graphical representation of the results:

Screenshot-2022-04-03-at-12.16.15-PMThe bar graph shows the better performance of Dash in comparison with Bash over multiple operations like variable assignment, logical comparison, counting operation, expression evaluation, function call, display operation, and sub-shell operations. The Dash shell is roughly 2-5 times more efficient than the Bash shell in terms of execution speed.

5. Conclusion

Thus from the above experiments, we conclude that the Dash shell, although with a smaller feature set, is much more efficient than the Bash shell in terms of both start-up time and execution speed.