Most shell scripts will utilize the echo command within their scripts simply to display an entry of text and then move on. However this only utilizes a small percentage of what can be accomplished using echo. Once you understand how to properly use echo within your bash scripts, it can become a very useful resource as a debugging output method for printing formatted logs, creating configuration files, and assisting in developing well structured automation pipelines. The following tutorial will cover all aspects needed to effectively use echo in shell scripting. Real-world examples are provided which many tutorials do not provide.
Why This Matters More Than You Think:
Most beginner scripts use echo in the same two or three ways. But here is what that leads to:
- Scripts that are hard to debug because there is no structured output
- Escape sequences that do not work because the wrong shell is being used
- Logs that get messy because no formatting was applied from the start
- Confusion about when to use echo vs printf, and which one to choose
This guide covers all of that, including the parts that other articles skip entirely.
If you are just getting started with shell scripting in general, it helps to first understand what bash scripting is and how it works on Linux before going deep on specific commands like echo.
What echo Actually Does (and Why It Is More Than Just Print)
There is the obvious piece of code for the echo command. It simply takes whatever is given to it as a string of characters and outputs that as a line to standard output. But the way this output gets treated by whatever runs the script is where things get interesting. The most common ways to treat this output would be to either save it in a file with redirection or send the result to another command with piping.
But there are also two flavors of the echo command on a typical Linux system. These are the stand alone echo binary located at /bin/echo, and the echo that is native to whatever shell you're using. While these echo commands work similarly for the most part, they do have one difference in terms of how certain edge conditions are treated. If you plan on running your scripts on multiple different Linux distributions, this could matter.
LinuxTeck.com
type echo
which echo
/usr/bin/echo
Good to know:
When you run echo in a bash script, it uses the built-in version by default. The built-in behavior is what this article focuses on. If you ever need to force the external binary, use /bin/echo directly. This becomes relevant when you are writing POSIX-compliant scripts for portability. Note that which echo only searches your $PATH for a binary, while type echo is what actually tells you what the shell will execute. Always use type when you need an accurate answer.
All echo Options and Flags Explained (With Real Examples)
Understanding the bash echo command options and flags is where most people stop reading other guides. Let us go through all the important ones with actual commands you can run right now.
The -n Flag: Remove the Trailing Newline
By default, echo adds a newline at the end of its output. The -n flag stops that. This is useful when you want to build output line by line or when you are prompting users without dropping to a new line.
LinuxTeck.com
df -hP / | awk 'NR==2{print $5}'
The -e Flag: Enable Escape Sequences
This is the flag that most people either forget about or use incorrectly. The -e flag tells echo to interpret backslash escape sequences instead of printing them literally.
LinuxTeck.com
echo -e "Name:\tJohn\nRole:\tSysAdmin"
Line two
Line three
Name: John
Role: SysAdmin
The -E Flag: Disable Escape Interpretation (Default)
If you want to make sure escape sequences are never interpreted (useful when the string contains backslashes that should stay literal), use -E. This is actually the default behavior but it is good to be explicit when writing scripts others will maintain.
LinuxTeck.com
Senior tip:
For truly literal strings like Windows paths, single quotes are safer. Single quotes prevent the shell from interpreting anything before echo even sees it: echo -E 'Path is: C:\Users\Admin'
Quick Reference: All Escape Sequences with -e
| Sequence | Meaning | Example output |
|---|---|---|
\n |
New line | Moves to next line |
\t |
Horizontal tab | Adds tab spacing |
\v |
Vertical tab | Vertical spacing |
\r |
Carriage return | Returns cursor to line start |
\b |
Backspace | Moves cursor back one |
\a |
Alert / bell | Triggers terminal bell sound |
\c |
Stop output here | Suppresses rest of string |
\\ |
Literal backslash | Prints one backslash |
Edge Case: Strings Starting with a Hyphen:
If you try echo "-n is a flag", echo will interpret -n as a flag and print nothing or behave unexpectedly. The fix is to use printf instead: printf -- "-n is a flag\n". The double dash tells printf that no more flags follow.
Internal link tip:
Escape sequences are also heavily used in text processing commands. If you work with sed or awk, many of the same patterns apply. See sed commands in Linux with examples for how these concepts extend to stream editing.
Echo with Variables, Redirection, and Command Substitution
Once you move beyond static text, echo becomes a lot more useful. Here are the core patterns that show up constantly in real scripts.
Printing Variables Safely
Always quote your variables when passing them to echo. Without quotes, word splitting can break your output if the variable contains spaces or special characters.
LinuxTeck.com
echo $username # risky if variable has spaces
echo "$username" # safe - always use double quotes
Redirecting echo Output to Files
This is one of the most common patterns in automation scripts. You can create files, overwrite them, or append to them all with echo.
LinuxTeck.com
echo "server=prod-01" | sudo tee /etc/myapp/config.conf
# Append to existing file
echo "port=8080" >> /etc/myapp/config.conf
# Write timestamped log entry (common in automation)
echo "$(date +"%Y-%m-%d %H:%M:%S") - Backup started" >> /var/log/myapp.log
Command Substitution with echo
You can embed the output of any command directly inside an echo string using $() syntax.
LinuxTeck.com
echo "Logged in as: $(whoami) on $(hostname)"
echo "Uptime: $(uptime -p)"
Logged in as: root on prod-server-01
Uptime: up 3 days, 7 hours
Common Mistake:
Using backticks `command` instead of $(command) for substitution. Backtick syntax is old and causes issues with nesting. Always use $() in modern scripts.
Fix: Replace echo "Time: `date`" with echo "Time: $(date)" and your scripts will be cleaner and easier to nest.
When you need to write multiple lines at once, it is also worth knowing about heredocs as an alternative to chaining several echo statements. See the Linux shell scripting command cheat sheet for a comparison of different output methods.
Using echo for Colored Output and Formatted Logs
Adding color to your script output is not just cosmetic. In automation pipelines and long-running scripts, color-coded output makes it far faster to spot errors, warnings, and success states at a glance. The echo command supports ANSI escape codes natively when you use the -e flag.
Basic Color Codes
LinuxTeck.com
# Color variables for reuse across the script
RED="\033[0;31m"
GREEN="\033[0;32m"
YELLOW="\033[1;33m"
BLUE="\033[0;34m"
NC="\033[0m" # No Color - resets all formatting
echo -e "${GREEN}[OK]${NC} Service started successfully"
echo -e "${YELLOW}[WARN]${NC} Disk usage above 80%"
echo -e "${RED}[ERROR]${NC} Connection to database failed"
echo -e "${BLUE}[INFO]${NC} Running backup job..."
[WARN] Disk usage above 80%
[ERROR] Connection to database failed
[INFO] Running backup job...
Pro Tip for DevOps Scripts:
Always end color sequences with ${NC} or \033[0m to reset formatting. If you forget this, every line after the colored one will inherit the same color and your terminal output becomes unreadable. Also define color variables at the top of your script once instead of repeating the escape code everywhere. This is the same discipline used in Linux bash scripting automation patterns for 2026.
Build a Reusable Logger Function Using echo
Instead of writing echo with colors every time, wrap it in a function that your scripts can call cleanly.
LinuxTeck.com
RED="\033[0;31m"; GREEN="\033[0;32m"
YELLOW="\033[1;33m"; NC="\033[0m"
LOGFILE="/var/log/myscript.log"
log_ok() { echo -e "${GREEN}[OK]${NC} $1"; echo "$(date +"%F %T") [OK] $1" >> $LOGFILE; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; echo "$(date +"%F %T") [WARN] $1" >> $LOGFILE; }
log_err() { echo -e "${RED}[ERROR]${NC} $1"; echo "$(date +"%F %T") [ERROR] $1" >> $LOGFILE; }
# Usage in your script:
log_ok "Apache service is running"
log_warn "SSL certificate expires in 7 days"
log_err "Could not reach backup server"
This pattern is used constantly in real-world sysadmin and DevOps scripts. For a deeper look at logging best practices in Linux, see Linux logging best practices.
echo vs printf: Which One Should You Use and When
This is probably the most commonly searched follow-up question after people learn echo, and none of the top competitor articles answer it properly. So here is a clear breakdown of echo vs printf in bash shell scripting.
The short version: printf is more consistent and portable across shells and systems. echo is faster to write for simple output but has some behavior quirks that can bite you.
| Feature | echo | printf |
|---|---|---|
| Simple text output | Easy, one-liner | Slightly more verbose |
| Escape sequences | Needs -e flag |
Always interpreted |
| Formatted numbers/padding | Not supported | Full C-style formatting |
| Portability (sh, dash, ash) | Inconsistent behavior | Consistent across shells |
| Trailing newline control | Needs -n flag |
No newline by default |
| Writing to variables | Not directly | Use with -v flag |
| Beginner friendliness | Very easy | Slight learning curve |
Practical Comparison: Side by Side
LinuxTeck.com
echo "Hello World"
printf "Hello World\n"
# Formatted table row - printf is clearly better
echo "Name: John Age: 30"
printf "%-12s %-5d\n" "John" 30
# Multiple lines - similar but printf is more portable
echo -e "First\nSecond\nThird"
printf "First\nSecond\nThird\n"
Quick rule of thumb:
Use echo for quick, simple one-line messages inside bash scripts. Use printf when you need formatted output, column alignment, or your script might run under different shells like sh or dash. If you are writing scripts that need to run on both Ubuntu servers and Alpine-based Docker containers, printf is the safer choice. For more on scripting foundations, check bash script hello world guide for beginners.
How echo Behaves Differently Across Linux Distros (Ubuntu, Rocky, Alpine)
This is the section that no other article on the echo command covers, and it is genuinely important if you write scripts that need to run on more than one type of Linux system. The behavior of the echo command in Linux can vary depending on which shell is being used as the default interpreter on each distro.
The problem shows up most with the -e flag and escape sequences. On some systems, echo -e works as expected. On others, the -e is printed as a literal character instead of being treated as a flag.
Distro Default Shell Behavior
| Distro | Default /bin/sh |
echo -e behavior |
Notes |
|---|---|---|---|
| Ubuntu | dash | Inconsistent with bash | dash's echo may print -e literally. Always use #!/bin/bash in scripts that use echo -e. |
| Rocky Linux 8/9 | bash | Works as expected | /bin/sh symlinks to bash on RHEL-based systems. echo -e works reliably. |
| CentOS / RHEL | bash | Works as expected | Same as Rocky. Consistent behavior across versions 7, 8, and 9. |
| Alpine Linux | ash (busybox) | Different behavior | Alpine uses busybox sh. Escape sequences in echo work differently. Use printf instead for portable scripts. |
The Fix: Always Use an Explicit Shebang
LinuxTeck.com
# never rely on #!/bin/sh if you need echo -e to work consistently
echo -e "\033[0;32m[OK]\033[0m Script running under bash"
Common Mistake on Ubuntu:
Writing #!/bin/sh at the top of a script on Ubuntu and then using echo -e. On Ubuntu, /bin/sh is dash, not bash. Dash's built-in echo treats -e as part of the string, not a flag, and prints it literally.
Fix: Change your shebang to #!/bin/bash or replace echo -e "text\ntext" with printf "text\ntext\n" for portability. This is one of the most searched errors on Ubuntu forums. See more about how bash and sh differ in what is bash scripting on Linux.
Testing echo Behavior on Your System
LinuxTeck.com
/bin/sh -c 'echo -e "test\nnewline"'
# If output starts with "-e test" then /bin/sh is dash or ash
# If you see two separate lines then it is bash
For Rocky Linux and RHEL users specifically, scripts with echo generally behave consistently. If you are managing Rocky Linux servers, see how this fits into broader administration tasks in the Linux system administration guide for 2026.
Troubleshooting: Why echo -e Is Not Working in Bash
This is one of the most common questions in bash forums we are targeting. Let us go through every scenario where echo behaves unexpectedly and how to fix each one.
Problem 1: echo -e Prints the Flag Literally
You type echo -e "hello\nworld" and see -e hello\nworld as the output instead of two lines.
Root cause: Your script is running under /bin/sh which on Ubuntu points to dash, not bash. Dash does not support the -e flag.
LinuxTeck.com
#!/bin/sh
echo -e "hello\nworld" # outputs: -e hello\nworld
# Fixed:
#!/bin/bash
echo -e "hello\nworld" # correctly outputs on two lines
# Or use printf for full portability across all shells:
printf "hello\nworld\n"
Problem 2: Backslash Sequences Are Printing Literally
You use echo "hello\tworld" and see hello\tworld instead of a tab.
Root cause: You forgot the -e flag. Without it, bash echo treats all backslash sequences as plain text.
LinuxTeck.com
echo -e "hello\tworld" # prints: hello world (tab applied)
Problem 3: Variable Is Empty or Shows Unexpected Value
You echo a variable and get nothing or wrong output.
LinuxTeck.com
name="Alice"
echo 'Hello $name' # output: Hello $name (literal)
# Correct: double quotes allow variable expansion
echo "Hello $name" # output: Hello Alice
Problem 4: Colors Not Showing in Terminal Output
ANSI color codes are printing as raw text instead of applying color.
LinuxTeck.com
echo "\033[0;32mGreen text\033[0m"
# Correct:
echo -e "\033[0;32mGreen text\033[0m"
# Also verify your terminal supports colors:
tput colors
Debugging Tip:
When a script is not producing the output you expect, add echo statements at different points in the script with variable values and the current step number. This is the simplest form of script debugging and it works on every Linux system without any additional tools. For more structured debugging, also look at the set -x option covered in the bash script exit codes and error handling guide.
Real-World DevOps and Automation Use Cases for echo in 2025
Here is where we go beyond the basic tutorial content. These are patterns that show up in real production scripts and none of the competing articles cover them at this depth.
Use Case 1: Generate Config Files Dynamically
Echo is commonly used to write configuration content to files as part of provisioning and deployment scripts.
LinuxTeck.com
DB_HOST="10.0.1.5"
DB_PORT="5432"
DB_NAME="appdb"
CONF_FILE="/etc/myapp/db.conf"
echo "[database]" > "$CONF_FILE"
echo "host = $DB_HOST" >> "$CONF_FILE"
echo "port = $DB_PORT" >> "$CONF_FILE"
echo "name = $DB_NAME" >> "$CONF_FILE"
echo "Generated config at $(date)"
Use Case 2: Timestamped Logging Inside Cron Jobs
Cron jobs run silently, so structured logging with echo is essential to know what happened and when.
LinuxTeck.com
# /etc/cron.daily/db-backup.sh
LOG="/var/log/db-backup.log"
BACKUP_DIR="/mnt/backups"
TS=$(date +"%Y-%m-%d_%H:%M:%S")
echo "[$TS] Starting database backup" >> "$LOG"
if mysqldump mydb > "$BACKUP_DIR/mydb_$TS.sql"; then
echo "[$TS] Backup completed successfully" >> "$LOG"
else
echo "[$TS] ERROR: Backup failed" >> "$LOG"
exit 1
fi
For more cron-based automation patterns, see cron command in Linux with examples.
Use Case 3: User Prompt Script with Validation
LinuxTeck.com
echo -n "Enter server hostname: "
read HOSTNAME
if [ -z "$HOSTNAME" ]; then
echo "ERROR: Hostname cannot be empty"
exit 1
fi
echo "Connecting to: $HOSTNAME"
When to Replace echo Chains with Heredoc:
If you are writing more than 5 or 6 echo statements to build a multi-line file or output block, consider switching to a heredoc instead. Heredocs are cleaner for writing full config files, email templates, or multiline scripts. The rule is simple: one or two lines, use echo. Three or more structured lines, use heredoc. This also avoids accidental quoting issues that can happen when echoing complex strings. See the Linux I/O redirection cheat sheet for heredoc examples.
echo Command Cheat Sheet: Copy-Paste Reference
Here is a quick-reference cheat sheet for the most commonly used echo command examples in shell scripting.
| Command | What it does | Example output |
|---|---|---|
echo "text" |
Print plain text | text |
echo -n "text" |
Print without trailing newline | text (cursor stays on same line) |
echo -e "a\nb" |
Enable escape sequences | a on line 1, b on line 2 |
echo -E "a\nb" |
Disable escape sequences (default) | a\nb (literal) |
echo "$VAR" |
Print variable value (quoted) | Value of VAR |
echo "$(cmd)" |
Print command output inline | Output of cmd |
echo "text" > file |
Write to file (overwrite) | Creates or overwrites file |
echo "text" >> file |
Append to file | Adds line to end of file |
echo -e "\033[0;32mOK\033[0m" |
Green colored output | OK (in green) |
echo -e "\t" |
Horizontal tab | Tab space |
echo -e "\n" |
Extra blank line | Newline |
echo * |
List files in current dir (like ls) | All file names |
echo $? |
Print last command exit status | 0 for success, non-zero for error |
For more command-line references, the Linux commands for beginners guide is a good companion to this article.
Frequently Asked Questions About echo in Linux
Why is echo -e not working in bash on Ubuntu?
This is the most common echo problem on Ubuntu systems. The reason is that on Ubuntu, /bin/sh points to dash, not bash. Dash does not support the -e flag in its built-in echo command, so it prints -e as literal text in the output.
The fix is straightforward. Make sure your script starts with #!/bin/bash instead of #!/bin/sh. Alternatively, replace echo -e with printf which works consistently across all shells including dash and ash.
LinuxTeck.com
echo -e "Line 1\nLine 2"
# or the portable version that works everywhere:
printf "Line 1\nLine 2\n"
For more about the difference between bash and sh on Linux, see what is bash scripting on Linux.
What is the difference between echo and printf in Linux?
The core difference is in portability and formatting control. echo is simpler and faster to write but behaves inconsistently across shells. printf requires you to explicitly add \n for newlines but works the same way on bash, dash, ash, and zsh.
Use echo for quick informational output inside bash scripts. Use printf when your script needs to run on multiple distros or different shell types, or when you need aligned columns and number formatting. A simple rule: if the output has to look exactly right regardless of the system, choose printf.
How do I print a variable value using echo in bash?
Always wrap variables in double quotes when passing to echo. This preserves whitespace and prevents unexpected word splitting if the variable value contains spaces or special characters.
LinuxTeck.com
echo "$name" # always use double quotes
echo "Server: $name" # embedding variable in a sentence
How do I add color to echo output in a shell script?
Use ANSI escape codes with the -e flag. Define color variables at the top of your script and always reset the color at the end of each colored string using \033[0m. Without the reset, all subsequent output inherits the color.
LinuxTeck.com
RED="\033[0;31m"
NC="\033[0m"
echo -e "${GREEN}Success${NC}: Operation completed"
echo -e "${RED}Failed${NC}: Could not connect"
Can echo write to a file and print to terminal at the same time?
Not with echo alone, but you can achieve this by piping the output through the tee command, which reads from stdin and writes to both stdout and a file simultaneously.
LinuxTeck.com
echo "Deployment started at $(date)" | tee -a /var/log/deploy.log
# tee -a appends; tee without -a overwrites
How is echo different on Rocky Linux versus Ubuntu?
On Rocky Linux (and other RHEL-based systems like CentOS), /bin/sh is a symlink to bash. So echo -e works as expected whether your script uses #!/bin/sh or #!/bin/bash.
On Ubuntu, /bin/sh points to dash. Dash does not support echo's -e flag. If your script uses #!/bin/sh on Ubuntu and relies on echo -e, the escape sequences will not work and -e will appear in the output literally. This is a real cross-platform portability issue that affects scripts moving between RHEL-based and Debian-based systems.
For more on Rocky Linux server setup and administration, see how to install Rocky Linux step by step.
Summary
Understanding how to properly use echo in shell scripts can be one of the many tiny differences that add up over time. Once you know how to flag the echo command appropriately; what happens when variables are used along side quotes; and how different versions of different distro's (like ubuntu & rocky linux) will behave regarding echoing input, then echo no longer is simply a "print" statement - but rather an actual useful tool within your own shell script.
If you would like to continue enhancing your scripting abilities you may also wish to review some of the Linux shell scripting interview questions to help challenge yourself.
Related Articles
Learn step-by-step how to automate Linux tasks with real-world scripts and practical examples.