Skip to content
Linux Basics: Format Output Explicitly with GNU printf

Linux Basics: Format Output Explicitly with GNU printf

October 27, 2026

Predictable shell output needs a fixed format string and data passed as separate arguments. This example invokes the external GNU printf through env, making the implementation explicit even when Bash has a builtin with the same name.

Prepare a scratch directory

Tested on Linux with GNU coreutils 9.7 and GNU Bash 5.2.37. You need the named runtime, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. The script creates a separate temporary fixture directory and removes only that directory on exit. It does not operate on your existing files.

Keep using the same terminal. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-gnu-printf.sh:

#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
cd -- "$fixture_dir"
printf 'Fixed-width table:\n'
env printf '%-8s %04d\n' alpha 7 beta 23
printf 'Untrusted-looking text treated as data:\n'
value='%s has a backslash: \n'
env printf '%s\n' "$value"
printf 'Explicit escape interpretation:\n'
env printf '%b' 'left\tright\n' | cat -T
printf 'Literal percent: '
env printf '%d%%\n' 50
env printf '%s\n' "$value" > value.txt
test "$(cat value.txt)" = "$value"

Run it:

bash demonstrate-gnu-printf.sh

Observed output:

Fixed-width table:
alpha    0007
beta     0023
Untrusted-looking text treated as data:
%s has a backslash: \n
Explicit escape interpretation:
left^Iright
Literal percent: 50%

Read the result

The format repeats as needed for the extra arguments, producing two table rows. %s emits the supplied value literally, including percent signs and backslash characters. %b deliberately interprets backslash escapes in its argument; cat -T makes the resulting tab visible. %% emits one percent sign from the format itself.

Apply it carefully

Keep externally supplied text out of the format string. Prefer %s for arbitrary text, and use %b only when escape interpretation is intended. Numeric formatting can have locale-dependent behavior; the fixture selects C. Bash’s builtin and the external GNU utility have overlapping but not identical options and conversions, which is why env printf is used for the demonstrated formatting operations. Formatting is not escaping for HTML, SQL, or a shell command.

The official reference describes the API and its options. The checks above cover the specific fixture, not every possible input or environment.

Clean up

Remove the source and then the empty practice directory:

rm -- demonstrate-gnu-printf.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect the remaining files rather than deleting unknown contents.

Acknowledgements

This post was created with assistance from AI.

Last updated on