ZetCode

Linux echo Command

last modified October 23, 2026

The echo command prints its arguments to standard output, separated by spaces and followed by a newline. It is used to display messages, show the values of variables, and write text to files from the shell and from scripts.

In Bash, echo is a shell builtin; a standalone /bin/echo from coreutils exists too. The behaviour of echo differs between shells, especially for escape sequences, so printf is preferred in portable scripts. The examples use Bash.

Printing text

echo prints its arguments separated by single spaces.

echo Hello, World!
echo Hello      there
echo "Hello      there"

Without quotes, the shell splits the text into words and echo joins them with single spaces, so the extra spaces disappear. Quotes pass the text as one argument with the spacing intact. Quoting also protects characters that are special to the shell, such as *, &, or ;.

$ echo Hello, World!
Hello, World!
$ echo Hello      there
Hello there
$ echo "Hello      there"
Hello      there

Variables

Variables are expanded inside double quotes but not inside single quotes.

name="Jan"
echo "Hello, $name"
echo 'Hello, $name'
echo "Home: $HOME, shell: $SHELL"

Single quotes print the text literally. Environment variables such as HOME and SHELL are expanded like any other variable. Always quote variables, so that their values are not split or expanded as wildcards.

$ name="Jan"
$ echo "Hello, $name"
Hello, Jan
$ echo 'Hello, $name'
Hello, $name
$ echo "Home: $HOME, shell: $SHELL"
Home: /home/jano, shell: /bin/bash

Command substitution and arithmetic

The output of commands and the results of calculations can be embedded in the text.

echo "Today is $(date -d 2026-10-23 +%A)"
echo "2 + 3 = $((2 + 3))"
echo "Files: $(ls | wc -l)"

$(command) is replaced with the output of the command, and $((expression)) with the result of integer arithmetic.

$ echo "Today is $(date -d 2026-10-23 +%A)"
Today is Friday
$ echo "2 + 3 = $((2 + 3))"
2 + 3 = 5
$ echo "Files: $(ls | wc -l)"
Files: 3

Suppressing the newline

The -n option omits the trailing newline.

echo -n "No newline"; echo " - continued"

The second echo continues on the same line. This is used for prompts and progress messages.

$ echo -n "No newline"; echo " - continued"
No newline - continued

Escape sequences

The -e option enables the interpretation of backslash escapes such as \n (newline), \t (tab), and \c (stop output).

echo "one\ttwo\nthree"
echo -e "one\ttwo\nthree"
echo -e "stop here\c and not here"; echo

By default, Bash's echo prints backslashes literally. With -e, the escapes are interpreted. \c suppresses all further output, including the newline, so we add an empty echo. The -E option explicitly disables escapes.

$ echo "one\ttwo\nthree"
one\ttwo\nthree
$ echo -e "one\ttwo\nthree"
one	two
three
$ echo -e "stop here\c and not here"; echo
stop here

Portability and printf

Different echo implementations treat escapes differently. The printf command behaves the same everywhere.

echo $'tab:\tend'
sh -c 'echo "one\ttwo"'
/bin/echo "one\ttwo"
printf "%s\t%s\n" one two

Bash's $'...' quoting interprets escapes before echo sees the text. On Debian, sh is dash, whose echo always interprets escapes, while the coreutils /bin/echo does not. A script using echo with backslashes can thus print different output depending on the shell. printf takes a format string and is the reliable choice for anything beyond simple messages.

$ echo $'tab:\tend'
tab:	end
$ sh -c 'echo "one\ttwo"'
one	two
$ /bin/echo "one\ttwo"
one\ttwo
$ printf "%s\t%s\n" one two
one	two

Wildcards and brace expansion

The shell expands unquoted wildcards and braces before echo runs, which makes echo a safe way to preview expansions.

echo *
echo *.txt
echo "*.txt"
echo file{1..3}.txt

The asterisk expands to the file names in the current directory. In quotes, it stays literal. Brace expansion generates sequences of words. Before running something like rm *.txt, echo *.txt shows which files would be affected.

$ echo *
data.csv notes.txt report.txt
$ echo *.txt
notes.txt report.txt
$ echo "*.txt"
*.txt
$ echo file{1..3}.txt
file1.txt file2.txt file3.txt

Writing to files and standard error

Redirection sends the output of echo to a file or to standard error.

echo "first line" > out.txt
echo "second line" >> out.txt
echo "error: file not found" >&2

> overwrites the file and >> appends to it. In scripts, error messages should go to standard error with >&2, so that they are not mixed with regular output. See redirection and pipes for more.

$ echo "first line" > out.txt
$ echo "second line" >> out.txt
$ cat out.txt
first line
second line
$ echo "error: file not found" >&2
error: file not found

Colours

ANSI escape sequences change the colour and style of terminal text.

echo -e "\e[1;31mError\e[0m: disk full"
echo -e "\e[1;31mError\e[0m: disk full" | cat -v

\e[1;31m switches to bold red, and \e[0m resets the attributes. In a terminal, the word Error appears in bold red; here in the second command, we pipe the output to cat -v to make the escape characters visible. Use colours only when writing to a terminal, which can be tested with [ -t 1 ].

$ echo -e "\e[1;31mError\e[0m: disk full" | cat -v
^[[1;31mError^[[0m: disk full

Printing arbitrary data

echo cannot print every string. A value that looks like an option is consumed instead of printed.

opt="-n"
echo "$opt"
printf "%s\n" "$opt"
echo -- "-n"

echo "$opt" prints nothing, because -n is taken as an option. Bash's echo does not support -- to end options, so it prints the dashes too. printf "%s\n" prints any value exactly, which is why it should be used for data such as user input or file contents.

$ opt="-n"
$ echo "$opt"
$ printf "%s\n" "$opt"
-n
$ echo -- "-n"
-- -n

Best practices for echo

Source

Bash manual: builtin commands

In this article, we have used the echo command to print text, variables, and command output, control newlines and escape sequences, write to files, and we have compared it with printf.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.