Skip to content
shellhacks.dev
Performance

Avoid a subshell for command substitution

Store a formatted string without a subshell using printf -v name. Command substitution forks a child for every call, which printf -v does not.

1 min read
Summarize in AI

A loop builds a string with x=$(printf ...), and each pass forks a subshell just to capture one line.

Shell
TIMEFORMAT='%3R seconds'
echo "command substitution:"
time (for i in {1..2000}; do x=$(printf '%05d' "$i"); done; echo "$x")
echo "printf -v:"
time (for i in {1..2000}; do printf -v x '%05d' "$i"; done; echo "$x")
Text
command substitution:
02000
1.367 seconds
printf -v:
02000
0.006 seconds

$(...) runs its contents in a subshell and reads the output through a pipe, even when the command is the printf builtin. printf -v var writes the result straight into the variable inside the current shell, as the printf builtin describes. The loops ran 2,000 times in a Debian 12 container on an arm64 laptop, so compare the two times and ignore the absolute values.

-v is a Bash feature and is not in POSIX sh. It also takes only one variable name, and with an array element as the target the subscript must be quoted if it contains a variable. For a loop of a few hundred iterations the difference is not noticeable, so write the clearer version first.

Share

More snippets

Performance

Count lines in a huge file fast

Count the lines of a big file with wc -l, which is the fastest of the usual tools. It counts newlines, so a last line without a newline is not counted.

2 min read
Performance

Find syscalls that take time

Show how long each system call takes with strace -T. The figure in angle brackets is the time spent inside the call, so a slow write or sleep stands out.

1 min read
Performance

Trace file opens of a command

Find which files a command opens with strace -e trace=openat, and add -e status=failed to see the config files it looked for and did not find.

2 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.