Programming
Error Handling
Standard Error
Command Line Tools
Unix/Linux

echo that outputs to stderr

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

By default, echo writes to stdout (file descriptor 1). To write to stderr (file descriptor 2), redirect stdout to stderr with >&2. This is essential in shell scripts to separate error messages and diagnostic output from normal output, allowing downstream commands and pipelines to process only the intended data while errors are displayed or logged separately.

Basic Redirect to stderr

bash
echo "Error: file not found" >&2

The >&2 operator redirects file descriptor 1 (stdout) to file descriptor 2 (stderr). The message is written to stderr instead of stdout.

bash
1# Verify: redirect stdout to /dev/null — stderr message still appears
2echo "This goes to stdout"
3echo "This goes to stderr" >&2
4
5# Run: script.sh > /dev/null
6# Output: "This goes to stderr" (stdout is discarded, stderr still shows)

Creating an stderr Echo Function

Define a reusable function for cleaner scripts:

bash
1# Define the function
2echoerr() {
3    echo "$@" >&2
4}
5
6# Usage
7echoerr "Error: invalid argument"
8echoerr "Warning: file is empty"

With printf (More Portable)

bash
1echoerr() {
2    printf '%s\n' "$@" >&2
3}
4
5echoerr "Error: connection refused"

printf is more portable across shells than echo, which has inconsistent behavior with escape sequences on different platforms.

Using cat for Multi-Line stderr Output

bash
1# Here-doc to stderr
2cat >&2 <<EOF
3Error: configuration file is missing.
4Expected location: /etc/myapp/config.yaml
5Run 'myapp --init' to create a default configuration.
6EOF

Practical Script Example

bash
1#!/bin/bash
2
3log_error() {
4    echo "[ERROR] $1" >&2
5}
6
7log_info() {
8    echo "[INFO] $1"
9}
10
11process_file() {
12    local file="$1"
13
14    if [ ! -f "$file" ]; then
15        log_error "File not found: $file"
16        return 1
17    fi
18
19    log_info "Processing $file"
20    # ... process the file ...
21    log_info "Done processing $file"
22}
23
24process_file "$1"
bash
1# Run the script — stdout and stderr go to different places
2./script.sh myfile.txt > output.log 2> error.log
3
4# output.log contains: [INFO] messages
5# error.log contains: [ERROR] messages

File Descriptors Explained

bash
1# File descriptor 0 = stdin  (input)
2# File descriptor 1 = stdout (normal output)
3# File descriptor 2 = stderr (error output)
4
5# Redirect stdout to a file
6echo "normal" > output.txt
7
8# Redirect stderr to a file
9echo "error" 2> error.txt    # Wrong: this redirects stderr of echo, not the output
10echo "error" >&2 2> error.txt # Wrong: order matters
11
12# Correct: redirect the echo's stderr output
13echo "error" >&2              # Writes to stderr
14# Then capture stderr at the caller level:
15./script.sh 2> error.txt

Redirecting Both stdout and stderr

bash
1# Redirect stdout and stderr to different files
2./script.sh > output.log 2> error.log
3
4# Redirect both to the same file
5./script.sh > all.log 2>&1
6
7# Bash shorthand (4.0+)
8./script.sh &> all.log
9
10# Pipe only stderr (swap descriptors)
11./script.sh 3>&1 1>&2 2>&3 | grep "ERROR"

stderr in Different Languages

python
1# Python
2import sys
3print("Error message", file=sys.stderr)
4
5# Or
6sys.stderr.write("Error message\n")
javascript
1// Node.js
2console.error("Error message");  // Writes to stderr
3console.log("Normal output");    // Writes to stdout
4
5// Explicit
6process.stderr.write("Error message\n");
go
// Go
fmt.Fprintln(os.Stderr, "Error message")
c
// C
fprintf(stderr, "Error message\n");

Why Separate stdout and stderr

bash
1# Pipeline only processes stdout — stderr passes through to terminal
2find / -name "*.conf" 2>/dev/null | grep "nginx"
3# Permission denied errors go to /dev/null
4# Found files pass through the pipe to grep
5
6# Without stderr redirection, errors pollute the pipeline
7find / -name "*.conf" | grep "nginx"
8# "Permission denied" lines mix with results

Separating stdout and stderr allows:

  • Piping normal output to other commands while displaying errors
  • Logging errors and output to different files
  • Suppressing errors with 2>/dev/null without losing output

Common Pitfalls

  • Redirect placement matters: echo "error" 2> file >&2 does not capture the message in file. The redirections are processed left to right, so 2> file redirects stderr (which is empty for echo) to the file, then >&2 sends stdout to the original stderr. Place >&2 on the echo command and redirect stderr at the script invocation level.
  • Forgetting >&2 in functions: If a function writes errors to stdout, those errors flow into pipes and corrupt downstream processing. Always use >&2 for error messages in functions used within pipelines.
  • echo -e portability: echo -e interprets escape sequences on some systems but prints -e literally on others (notably macOS/BSD). Use printf instead of echo -e for portable escape sequence handling.
  • Losing stderr in subshells: result=$(my_command) captures only stdout. stderr still goes to the terminal. To capture stderr, use result=$(my_command 2>&1) — but this mixes stdout and stderr into one string.
  • >&2 vs 2>&1: >&2 redirects stdout to stderr (for sending output to stderr). 2>&1 redirects stderr to stdout (for combining streams). They do opposite things and are frequently confused.

Summary

  • Use echo "message" >&2 to write to stderr
  • Create a helper function (echoerr) for repeated use in scripts
  • >&2 redirects stdout (fd 1) to stderr (fd 2)
  • Separating stdout and stderr keeps pipelines clean and allows independent logging
  • Use printf instead of echo for portable behavior across shells
  • Redirect stderr at the script invocation level with 2> to capture errors

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.