The Few Differences between Echo And Printf in Bash

Pavol Kutaj
3 min readDec 25, 2021

--

The aim of this pageđź“ťis to understand the difference between echo and printf commands in bash for printing into the console. I have encountered this when trying to stylize an output and print out the message with tab indentation (See the SO thread, too).

Comparing with PowerShell: the difference I utilize in posh is between write-host and out-host cmdlets, the former applying .toString() the latter not handling the formatting of an object at all. Let’s go back to bash:

  • echo has different versions across shells
  • these versions can treat special chars and their escaping differently
  • printf is the portable command for more sophisticated formatting than echo
  • printf uses format string as its first argument
~                  | `echo`                    | `printf`
-------------------|---------------------------|-------------------
newline | automatic | manually add `\n`
variables | var substition `${<var>}` | format string `%s`
formatting | unsupported | special syntax
output to variable | unsupported | `-v` flag

2. newlines

2.1. echo

  • prints args to stdout followed by a newline
root@fba933f1c0c4:~# echo "hello"
hello
  • there are 2 options for echo:
  • -n suppresses the newline
  • -e allows the use of escape sequences
  • using these options are generally discouraged, as they are not portable

2.2. printf

  • printf does not print a newline at the end by default
root@fba933f1c0c4:~# printf "hello"
helloroot@fba933f1c0c4:~# printf "hello
"
>>> hello
root@fba933f1c0c4:~#

3. variables

3.1. echo

$ var="world"
$ echo "hello ${var}"
hello world

3.2. printf

  • the special char %s denotes that you expect to read that string as another argument of the command
  • note that I did not add just for the sake of repetition of the previous point
$ var="world"
$ printf "hello %s" $var
hello world$
  • you can also provide a list of strings as an argument that activates a loop — note how essential the newline is
$ printf "p%st" a e i o u
patpetpitpotputpkutaj$
$ printf "p%st
" a e i o u
pat
pet
pit
pot
put
  • if there are >1 %s characters, printf maps them to args
$ printf "The home folder of %s is %s
" $USER $HOME
The home folder of pkutaj is /home/pkutaj
  • if you put a different count of args bash will be mapping them to the count of %s in a string
h$ printf "The home folder of %s is %s
" $USER $HOME a e i
The home folder of pkutaj is /home/pkutaj
The home folder of a is e
The home folder of i is

4. formatting

4.1. printf

  • the 20 after % code means that values are printed in columns that are 20 chars wid
  • in the example, it pads filenames with spaces (example has files way under 20 chars of length)
$ printf "|%20s |%20s |%20s |
" $(ls)

| b02_01.sh | b11_01.sh | b13_01.sh |
| b13_04.sh | b13_05.sh | b13_06.sh |
| b16_01.sh | b21_01.sh | b25_01/ |
| b25_01.sh | b27_01.sh | b27_02.sh |
| b43_01.sh | bash_board.md | hello.sh |
| notes.txt | shoppingnotes.txt | test/ |

5. output to a variable

5.1. printf

$ printf -v hello "Hello %s how are you
" $USER
$ echo $hello
Hello how are you

6. links

--

--

Pavol Kutaj

Today I Learnt | Infrastructure Support Engineer at snowplow.io with a passion for cloud infrastructure/terraform/python/docs. More at https://pavol.kutaj.com