The Few Differences between Echo And Printf in Bash
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 thanecho
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