Advanced Bash Scripting
Streams
printf
In Unix-like systems, printf is a POSIX-standard command for producing formatted output in the terminal. Unlike echo, which is usually a shell builtin, printf is an external executable that you invoke each time – trading a slight performance cost for precise control over formatting, field widths, alignment, and escape sequences.
echo vs printf
When you run echo, the shell handles it internally:
$ echo "Hello, world!"
Hello, world!
By contrast, printf is an external program:
$ printf "Hello, printf!\n"
Hello, printf!
Note
Because printf is external, the shell forks a new process to execute it. Despite this overhead, printf offers richer formatting capabilities and consistent behavior across different shells.

Format Specifiers
printf uses format specifiers similar to C's printf(). Here are the most common ones:
| Specifier | Description | Example |
|---|---|---|
%s | String | printf "%s\n" "text" |
%d | Signed integer | printf "%d\n" 42 |
%f | Floating-point number | printf "%.2f\n" 3.14159 |
%o | Octal representation | printf "%o\n" 10 |
%x/%%X | Hexadecimal (lowercase/uppercase) | printf "%x\n" 255 |
%% | Literal percent sign | printf "%%\n" |
Example: Strings and Numbers
#!/usr/bin/env bash
course="Advanced Shell Scripting"
printf "Welcome to the %s\n" "$course"
name="Alice"
age=28
weight=65.2
printf "Name: %s | Age: %d | Weight: %.1f kg\n" \
"$name" "$age" "$weight"
This prints:
Welcome to the Advanced Shell Scripting
Name: Alice | Age: 28 | Weight: 65.2 kg

Escape Sequences and Portability
Different shells handle echo escape sequences inconsistently. For example:
$ echo "Line1\nLine2"
Line1\nLine2
$ echo -e "Line1\nLine2"
Line1
Line2
To ensure portability, use printf which interprets \n, \t, and other escapes by default:
$ printf "Line 1\nLine 2\n"
Line 1
Line 2
Warning
Avoid relying on echo -e for escape handling across scripts. Use printf for consistent results in Bash, Dash, Zsh, and other POSIX-compliant shells.
Return Status and Character Count
printf returns an exit status (0 on success) and you can pipe its output to wc -c to count characters:
#!/usr/bin/env bash
message="Hello, world!"
if printf "%s" "$message"; then
count=$(printf "%s" "$message" | wc -c)
echo -e "\nPrinted $count characters successfully."
else
echo "Error: printf failed with code $?"
fi
References
Watch Video
Watch video content
Practice Lab
Practice lab