How to do console colors in bash script
01:24 31 Dec 2025

Title: Bash echo -e prints raw ANSI escape codes instead of colors in console (why am I seeing [0;36m?)

I am losing my mind over what should be a trivial Bash problem, and I want to be extremely explicit because I feel like I’m missing something fundamental.

I have a Bash script that prints status headers using ANSI color escape codes. The script runs, the output prints, but instead of seeing colored text, I see the literal escape sequences printed to the console, for example [0;36m instead of cyan text.

This is not a theoretical question — this is happening in a real script, in a real environment, and I cannot tell whether the issue is Bash, echo, the shell, the terminal, or the execution environment.


What I expect

I expect pretty colors in the console.

enter image description here


What I actually get

Instead, I see this in the console output:

enter image description here

So clearly the escape codes are being printed, not interpreted.


Relevant code (simplified but real)

CYAN="\033[0;36m"
NC="\033[0m"

echo -e "${CYAN}==============================${NC}"
echo -e "${CYAN}Terminus Task Difficulty Calibration${NC}"
echo -e "${CYAN}==============================${NC}"

I am explicitly using:

  • #!/usr/bin/env bash
  • echo -e
  • Standard ANSI escape sequences
  • A normal-looking terminal output

And yet… no color.


Screenshot evidence

On the left, you can see the Bash source code using ${CYAN}. On the right, you can see the console output literally printing [0;36m.

(Imagine screenshot here showing exactly that.)


Where this is running

This may be the key, which is why I’m spelling it out:

  • The script is executed in non-interactive contexts

  • Sometimes locally

  • Sometimes through:

    • CI-style runners
    • Remote SSH execution
    • Job logs rendered in a web UI
  • The output is not always a direct interactive terminal (TTY)

However:

  • The output does preserve other formatting (newlines, spacing, etc.)
  • It is not obvious to me whether ANSI is being stripped, escaped, or just ignored

Things I have already tried (so please don’t suggest them blindly)

  • Using echo -e
  • Using echo $'\033[0;36mtext\033[0m'
  • Exporting variables
  • Running the script directly vs sourcing it
  • Verifying $TERM (it is usually xterm-256color)
  • Verifying the shell is actually Bash
  • Making sure I am not in sh
  • Swearing at my computer

Same result.


The confusing part

If I run other scripts that use ANSI color, they sometimes work.

If I paste ANSI escapes directly into the terminal, they sometimes work.

But this script, when executed as part of a job or log output, prints raw escape codes.

So my working theory is one of the following (but I want confirmation):

  1. echo is unreliable and should not be used for ANSI output
  2. The output stream is not a TTY, so ANSI is not interpreted
  3. The environment capturing stdout is escaping ANSI
  4. The terminal emulator / log renderer does not support ANSI
  5. I am misunderstanding how ANSI color actually works in Bash

The actual question

Why is my Bash script printing raw ANSI escape codes instead of colored output, and what is the correct, portable, non-bullshit way to print colored text in Bash that works across real-world environments (including CI / SSH / job logs)?

Bonus points if the answer explains:

  • When ANSI colors cannot work
  • How to detect that case
  • Whether printf is required instead of echo
  • Whether I should just give up and remove color entirely

I am not looking for “works on my machine” answers. I want to understand why this fails and what the correct approach is.

bash colors console