Skip to content
Vidar Holen edited this page May 23, 2018 · 1 revision

Use { ..; } instead of (..) to avoid subshell overhead.

Problematic code:

([ "$x" ] || [ "$y" ]) && [ "$z" ]

Correct code:

{ [ "$x" ] || [ "$y" ]; } && [ "$z" ]

Rationale:

You appear to be using (..) to group test commands. This creates a subshell, making it unnecessarily slow. Avoid this by using { ..; } to group.

Be careful to note that unlike (..), this requires both a space after the { and a semicolon before the }.

For example, (cmd), (cmd;) and ( cmd ) are all valid, but {cmd}, {cmd;} and { cmd } are all syntax errors because they lack either or both of the spaces and semicolon. The correct form is { cmd; }

Here's a small benchmark showing that the subshell version is more than 100x slower:

$ i=0; time for i in {1..10000}; do ([ "$x" ] || [ "$y" ]) && [ "$z" ]; done
real    0m7.122s
user    0m4.204s
sys     0m2.825s

$ i=0; time for i in {1..10000}; do { [ "$x" ] || [ "$y" ]; } && [ "$z" ]; done
real    0m0.055s
user    0m0.055s
sys     0m0.000s

Exceptions:

None.

Related resources:

  • Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!

ShellCheck

Each individual ShellCheck warning has its own wiki page like SC1000. Use GitHub Wiki's "Pages" feature above to find a specific one, or see Checks.

Clone this wiki locally