Echo vs Printf in Bash: What’s the Difference?

Echo and printf can both be used in bash for outputting text. However, echo is for quick output, whereas printf gives you more power.

On this page
  1. Automatic Newline Insertion
  2. Printf’s Formatting Power
  3. Escape Sequences Portability
  4. Echo is Still the Preferred Tool
  5. Conclusion

We’re all familiar with echo. It’s the first command we learn when we’re introduced to Linux and bash, and it’s tremendously useful for getting the outputs of scripts, debugging, and more. It’s so prevalent, in fact, that we rarely use the alternative – printf. And with good reason. Printf is harder to use because it doesn’t have the same defaults that echo does, and most of the time it’s not necessary. But if you desire compatibility across Linux systems for non-trivial outputs, or if you want an output that is always predictable, then you should consider printf instead of echo. Let’s look at some of the differences between them and why it’s sometimes better to use printf instead of echo.

#Automatic Newline Insertion

The “echo” statement adds a newline by default whenever it outputs a string of text. We don’t notice this because in most cases, we want it to insert a new line. If it doesn’t, strange things will happen. Let’s illustrate this with an example.

I’ll first create a file using the output from an “echo” statement, and then append another line to the file. Here’s what happens:

Echo Adds a Newline

The above sequence of events is so common as to hardly be worth mentioning. We’ve all done it dozens of times, and it works perfectly. You add one line, then another, and the output looks great.

But what happens when echo doesn’t add a new line?

In contrast to the “echo” statement, “printf” doesn’t add a newline by default. And the consequences of this are visible in the following screenshot:

Printf Doesnt Add a Newline

Printf Doesn’t Add a Newline

We notice two things here.

First, the second printf statement is on the same line as the first one. This is NOT the behavior we expect. Second, the shell prompt itself is on the same line! This is definitely not what we want! We begin to see how much work the “echo” statement was doing behind the scenes to keep our environment clean and tidy.

#Printf’s Formatting Power

Echo is great for unformatted text that doesn’t require any specific way of being displayed. It works perfectly well for debug messages, informational outputs, and standard text. As long as you don’t care about the precise locations of newlines, specific formatting of numbers, alignment, and more, echo works admirably.

But this isn’t always the case. There are many situations where you need to generate a file name with a specific number of leading zeroes, for example, or situations where you need to display data in a table with specific alignment. Or what about the formatting of a certain poem? While echo has ways to insert newlines and tabs manually, these are notoriously unreliable between systems, and there’s no guarantee that you’ll get the same output in every environment.

When formatting is a factor, there’s no alternative to printf. Let’s look at a few examples.

Let’s say we require that a certain decimal number be only displayed with two digits of precision. So we want something like:

Code
3.14159

To be shown as:

Code
3.14

With echo, there’s no native formatting option that allows you to use this. You’ll have to use a separate function for this if you want to see numbers in a certain way. With printf, however, it’s simple. We use:

printf “Value: %.2f\n” 3.14159

This gives the following output:

Formatting a Number

This is exactly what we want. The format is simple. We use “format specifiers” as placeholders in printf, and provide the numbers as arguments. The “%” is the start of a specifier, and the “.2” tells printf to only print two digits after the decimal point. Finally, the “f” tells it to expect a floating-point number as an argument. We end it with a “\n” newline.

Those of you who are familiar with the “C” programming will recognize this way of outputting information. You essentially create a “template” within the quotation marks, and then specify the variables outside it in the order in which they appear inside the template. It’s incredibly flexible and also lends itself well to programming loops like this:

Code
for i in {1..5}; do
    printf "Step %02d: Processing...\n" $i
done

This gives the output:

Printf Output in a Loop

Of course, you can do this with echo as well, but as shown, the formatting could be difficult to get right. If your string is something simple like the above example, I would suggest just using echo instead.

With printf, you can also create alignments that would be much harder to do consistently with echo. Here’s an example where we insert 10 spaces before a word to get it to right-align within a set of square brackets:

Code
printf "[%10s]\n" "hi"

This gives the following:

Right-Align with Printf

Right-Align with Printf

As you can see, the formatting options with printf allow for all kinds of precise positioning that would be impossible with echo.

#Escape Sequences Portability

Echo has a problem with the way it executes escape sequences. Or more specifically, it has a problem with portability. It’s notoriously inconsistent between environments, and this is problematic because you want your script to work the same way in all Linux environments, and not have it depend on the specific flavor or version of bash.

Take the basic newline. In echo, if you want to print two lines one underneath the other, you can try this:

Code
echo "line1\nline2"

The problem is that it might or might not work, depending on the environment. In the bash environment that I currently use, it does not work. I need to use the “-e” parameter like this:

Code
echo -e "line1\nline2"

Here are the two commands side by side:

Two Newlines Side by Side

So we’ve found the rule that works on my set up, but there’s no guarantee that it’ll work the same way in another. And that’s where printf comes in.

With printf, escape sequences are always printed exactly as written. So the following command works perfectly in all environments:

Code
printf "line1\nline2\n"

Printf Newlines

Printf Newlines

Similarly, we have the following commands that allow us to print tabs and backslashes:

Code
printf "tab:\tend\n"

and

Code
printf "backslash: \\ \n"

So if your text relies heavily on escaping characters, then I suggest you use printf instead of echo for compatibility across all environments.

#Echo is Still the Preferred Tool

Despite the benefits of printf, there’s something to be said for simplicity. The echo statement works perfectly fine in most situations, and that’s what you should be using by default. Most of the time, we want a new line, and we’re not escaping characters. For simple debugging statements and outputs, echo is not just easier to use, it’s also easier to read. The power of printf makes sense only when you have special formatting requirements or have a lot of escape sequences. Power isn’t great for its own sake. There’s a reason why echo is still the tool of choice in most situations.

#Conclusion

For most situations, echo works just fine, and it’s easier to use. But when you have serious formatting requirements or need a lot of escape sequences in your string, then printf is the superior choice. For portability and predictable behavior in bash, printf is better when you have even remotely complex string output requirements. Printf gets its power from the syntax adopted by the C programming language, and its where it gets its flexibility.

Photo of Bhagwad Park
Written by

Bhagwad Park

Bhagwad Park writes for the NameHero blog.

More from Bhagwad →