Where to start First steps track · 15 stages
Linux Labs

printf and echo — printing text in scripts

4 min bash / coreutils

Formatted output in the shell — more reliable than echo, formats and special characters.

Cheat sheet

7 commands Printable version
  • printf '%s\n' "$var" a reliable way to print a string
  • printf '%-10s %5d\n' name 42 alignment
  • printf '%.2f\n' 3.14159 two digits after the point
  • printf '%05d\n' 42 leading zeros
  • printf -v v '%s' "$x" into a variable
  • printf '%(%F)T\n' -1 a date, without calling date
  • printf '%q\n' "$s" escape for the shell

Overview

echo prints a string; printf prints according to a format (like in C) and behaves predictably across systems. In scripts (bash-scripting), printf is preferred for careful output. See also the echo entry.

bash
echo "Hello"
printf '%s\n' "Hello"             # %s — a string, \n — a newline

Options

4

printf barely has any options of its own — control happens through the format string; the exception is -v, which writes the result into a variable instead of printing it. echo's options, by contrast, define its whole behavior: -n drops the trailing newline, -e/-E turn interpretation of \n/\t in the argument on and off — the default behavior of -e differs between bash's echo and /bin/echo, which is why printf is more reliable in scripts.

Option What it does Example
-v var printf: store the result in a variable instead of printing it. printf -v stamp '%(%Y%m%d)T' -1
-n echo: suppress the trailing newline. echo -n "no newline"
-e echo: interpret backslash escapes (\n, \t) in the argument. echo -e "a\tb"
-E echo: do not interpret backslash escapes (the default behavior). echo -E "a\tb"

Nothing found. Try a shorter query.

Recipes

2

Format

bash
printf '%s = %d\n' "port" 80                  # port = 80
printf '%-10s %5d\n' "nginx" 1234             # alignment: left-pad 10, right-pad 5
printf '%.2f\n' 3.14159                        # 3.14 (two digits)
printf '%05d\n' 42                             # 00042 (leading zeros)
printf '%x %o %b\n' 255 8 'a\tb'              # ff / 10 / a<tab>b (%b interprets escapes in the argument)
printf '%q\n' "a b'c"                          # safely escape for the shell
printf 'IP: %s\tPort: %s\n' 10.0.0.1 80        # \t — a tab
printf '%(%Y-%m-%d)T\n' -1                     # a date, without calling date (bash)
Specifier Meaning
%s %d %f string / integer / float
%-Ns %Nd width N (- = left-aligned)
%.Nf N digits after the decimal point
%05d leading zeros
%x %o hex / octal
%b a string with \n \t interpreted
%q escape for re-entry into the shell
%% a literal percent sign

More recipes

bash
# a table
printf '%-15s %-8s %s\n' NAME PID STATE
printf '%-15s %-8d %s\n' nginx 1234 running

# the format repeats for extra arguments:
printf '%s\n' a b c                # a / b / c, one per line

# build a string into a variable (no output):
printf -v stamp '%(%Y%m%d-%H%M%S)T' -1
echo "backup-$stamp.tar.gz"

# repeat a character N times (a separator):
printf '=%.0s' {1..40}; echo

Troubleshooting

4

echo mangled a string with a dash or a backslash

echo "-n", or strings with \, behave unpredictably between shells. Use printf '%s\n' "$var" (see echo).

printf truncated/repeated the output

printf applies the format to all arguments, cycling through it. More arguments than % specifiers → the format repeats (this is a feature, for lists). Fewer → the missing ones are treated as empty/0.

You need to build a string from variables

printf -v var '%s-%s' "$a" "$b" writes it into a variable with no output.

%d: invalid number

%d received something that isn't a digit. Check the argument; for arbitrary text, use %s.

See also

  • bash-scripting — Variables, conditionals, loops, arguments and the safe set -euo pipefail mode.
  • text-tools — Processing text and streams — sorting, uniqueness, columns, counting.
  • files-basics — Navigation and files — ls, cd, cp, mv, rm, cat, less, head, tail, copy-paste in the terminal.
Loading…