echo off vs @echo off: What’s the difference?

People with at least a passing interest in batch scripting may have noticed that all scripts begin with the same line:

@echo off

The more technically inclined reader already knows that this command disables outputting command names in the Command Prompt window, but may still wonder why there is a leading @ sign. The best way to find out is to see a script in action. We won’t be showing something that pushes the boundaries of reality: it’s a simple Hello World program. Our aim here is to show how that script will look inside a Command Prompt window in the cases where we don’t use echo off at all, we use echo off and we use @echo off.

Case #1: No echo off at all

Our sample script only contains two lines:
echo Hello World!
echo I'm a script!

When we run it, this is what happens:

Whenever the program is run, not only does the Command Prompt show every command that’s being run, but it still displays the active folder. As you can imagine, this isn’t very readable, for relevant information may get lost in the tens of lines of output.

Case #2: Using echo off

Let’s edit our sample script by adding echo off at the beginning. Our code is as follows:

echo off
echo Hello World!
echo I'm a script!

Let’s see what happens when we run it:

This looks much better, but notice how the command echo off is still displayed when we run the script. To prevent this, we will need to use @echo off.

Case #3: Using @echo off

Our code is identical to that in the previous example, save for a leading @ at the beginning of the first line:

@echo off
echo Hello world!
echo I'm a script!

Running our code produces the following output:

This is the most desirable result of the three, if you ask me.

Using @ to suppress a command’s output

Of course, the usefulness of @ doesn’t end here. It’s extremely useful when inside a for loop. Take this example:

for /f "tokens=*" %i in ('dir /b') do copy "%i" "%i.bak"

This line creates copies of the files within a folder and appends .bak at the end of their name. It’s simple enough. Let’s see what happens when we run it:

As expected, this isn’t very readable. We can slightly alter the above command by adding a @ before copy, like this

for /f "tokens=*" %i in ('dir /b') do @copy "%i" "%i.bak"

Running this altered cycle results in this output:

Pro-tipPro-tip: If you want to get to see the names of the files being copied, use the following command:

for /f "tokens=*" %i in ('dir /b') do @echo %i && @copy "%i" "%i.bak"

About Andrea Luciano Damico 126 Articles
Andrea Luciano Damico is a freelance translator from Italy. Among his interests are linguistics, technology, video games, and generally being a chill guy. He runs Let's Translate.it and Tech4Freelancers.net.