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