Команда echo -e "\033[31mОшибка\033[0m" в Bash выводит слово «Ошибка» красным цветом — и это самый быстрый способ проверить, поддерживает ли ваш терминал коды управления. Если вместо цветного текста вы видите набор символов вроде [31m, значит, эмулятор терминала не интерпретирует escape-последовательности, и это первое, что нужно диагностировать.

Коды управления терминалом — это невидимые служебные последовательности, которые текстовый терминал воспринимает не как обычные символы, а как команды: изменить цвет, очистить экран, переместить курсор. Они используются в скриптах, логах, консольных утилитах и при разработке CLI-приложений. В этой статье разберём, как устроены эти коды, какие из них стандартизированы, а какие зависят от конкретного эмулятора терминала.

Что такое управляющие коды и как они работают

Терминал исторически был физическим устройством — дисплеем с клавиатурой, подключённым к мейнфрейму. Чтобы программа могла не только печатать текст, но и управлять экраном, производители ввели управляющие последовательности: специальные комбинации байтов, начинающиеся с символа ESC (код 27 в таблице ASCII, шестнадцатеричное 0x1B).

Современные терминалы — это программы-эмуляторы: Windows Terminal, iTerm2, GNOME Terminal, xterm и другие. Все они в той или иной степени воспроизводят поведение классических устройств, чаще всего стандарта ANSI X3.64 и терминала DEC VT100. Когда программа выводит последовательность ESC[2J, эмулятор очищает экран, а когда получает ESC[1;32m — переключает цвет текста на ярко-зелёный.

Символ ESC можно записать в коде по-разному в зависимости от языка и оболочки:

  • 🔹 \033 — восьмеричная запись, работает в Bash и C;
  • 🔹 \x1b — шестнадцатеричная запись, привычна в Python и C;
  • 🔹 \e — сокращение, поддерживаемое в echo -e и многих языках;
  • 🔹 \u001b — Unicode-форма в Python 3 и JavaScript.
💡

Любая ANSI-последовательность начинается с символа ESC (0x1B). Если терминал показывает коды как текст — проблема в эмуляторе или в способе вывода, а не в самих кодах.

Структура ANSI escape-последовательностей

Большинство современных кодов относятся к типу CSI (Control Sequence Introducer) и имеют вид ESC[параметры;буква. Завершающая буква определяет действие: m — оформление текста, J — очистка, H — позиционирование курсора. Параметры перечисляются через точку с запятой.

Например, последовательность ESC[1;31m расшифровывается так: параметр 1 включает жирное начертание, параметр 31 — красный цвет текста, буква m означает команду SGR (Select Graphic Rendition). Сброс всех атрибутов выполняется кодом ESC[0m — его важно добавлять после цветного фрагмента, иначе раскраска «протечёт» на весь последующий вывод.

printf '\033[1;31mВнимание!\033[0m Обычный текст\n'
⚠️ Внимание: забытый код сброса ESC[0m — самая частая причина «сломанного» терминала, когда весь текст после цветного сообщения остаётся красным или жирным. Всегда завершайте оформленный фрагмент сбросом атрибутов.

Цвета и оформление текста

Базовая палитра SGR включает восемь стандартных цветов для текста (коды 30–37) и фона (коды 40–47). Яркие варианты доступны кодами 90–97 и 100–107. Кроме цвета, SGR управляет начертанием: жирный (1), курсив (3), подчёркивание (4), инверсия (7), зачёркивание (9).

КодДействиеПример последовательности
0Сброс всех атрибутовESC[0m
1Жирный / повышенная яркостьESC[1m
31Красный текстESC[31m
42Зелёный фонESC[42m
4ПодчёркиваниеESC[4m

Помимо базовой палитры, многие эмуляторы поддерживают 256-цветный режим (ESC[38;5;Nm, где N — номер цвета от 0 до 255) и true color с 24-битными значениями (ESC[38;2;R;G;Bm). Однако поддержка этих режимов зависит от конкретного терминала: перед использованием в скриптах проверьте переменную окружения TERM и документацию вашего эмулятора.

💡

Проверить поддержку 256 цветов можно командой `tput colors` — она выведет максимальное число цветов для текущего значения TERM.

📊 Где вы чаще всего применяете коды управления терминалом?
Bash-скрипты и автоматизация
CLI-приложения на Python/Node.js
Раскраска логов и мониторинг
Только изучаю тему

Управление курсором и экраном

Вторая большая группа кодов отвечает за перемещение курсора и очистку областей экрана. Именно они позволяют создавать динамические интерфейсы: индикаторы прогресса, обновляющиеся таблицы, мигающие статусы — всё это делается перезаписью строк вместо вывода новых.

Основные последовательности этой группы:

  • 🖱️ ESC[nA / ESC[nB — курсор на n строк вверх / вниз;
  • 🖱️ ESC[nC / ESC[nD — курсор на n позиций вправо / влево;
  • 🖱️ ESC[строка;столбецH — переход в абсолютную позицию;
  • 🖱️ ESC[2J — очистка всего экрана, ESC[K — очистка от курсора до конца строки;
  • 🖱️ ESC[s и ESC[u — сохранить и восстановить позицию курсора.

Классический пример — прогресс-бар, обновляющийся на одной строке. Вместо перевода строки используется возврат каретки \r и повторный вывод:

for i in $(seq 0 10 100); do

printf '\rПрогресс: %d%%' "$i"

sleep 0.2

done

printf '\n'

Обратите внимание: \r — это не CSI-последовательность, а обычный управляющий символ ASCII (код 13), однако в связке с ANSI-кодами он используется постоянно. Для скрытия курсора во время анимации применяется ESC[?25l, а для возврата видимости — ESC[?25h.

⚠️ Внимание: если скрипт со скрытым курсором завершится аварийно, курсор в терминале «пропадёт». Вернуть его можно командой printf '\033[?25h' или полным сбросом терминала командой reset.

☑️ Безопасная работа с кодами управления

Выполнено: 0 / 4

Коды управления в Windows, Linux и macOS

Исторически консоль Windows (cmd.exe) не понимала ANSI-коды — там использовался отдельный Console API. Начиная с обновлений Windows 10, в conhost появилась поддержка виртуальных терминальных последовательностей, а Windows Terminal и PowerShell работают с ними по умолчанию. Точное поведение зависит от версии системы, поэтому для кроссплатформенных скриптов проверяйте окружение.

В Python проблему совместимости решает библиотека colorama: она перехватывает ANSI-коды и конвертирует их в вызовы Windows API там, где это нужно. В Linux и macOS никакой прослойки не требуется — эмуляторы терминалов там изначально построены вокруг ANSI-стандарта.

Пример вывода цветного текста на Python без сторонних библиотек:

print('\033[1;32mУспешно\033[0m: операция завершена')
Почему в лог-файлах видны странные символы вроде [32m

Когда вывод программы перенаправляется в файл, escape-последовательности записываются туда как есть — в виде байтов. Поэтому логи, просматриваемые через less или редактор, «засоряются» кодами цветов. Решение: перед раскраской проверять, подключён ли вывод к терминалу (isatty() в Python, test -t 1 в Bash), и отключать цвета при записи в файл.

Диагностика типичных проблем

Если коды не работают, причина обычно находится в одном из трёх мест: способ вывода, эмулятор терминала или перенаправление потока. Разберём каждый сценарий.

Первый случай — коды выводятся как текст. Чаще всего виноват echo без флага -e: по умолчанию он не интерпретирует обратные слэши. Используйте echo -e или, что надёжнее, printf, который стандартизирован POSIX и ведёт себя предсказуемо в разных оболочках.

Второй случай — терминал не поддерживает последовательность. Старые или минималистичные эмуляторы (например, некоторые встроенные консоли IDE) могут игнорировать часть кодов. Проверьте значение echo $TERM: значения вроде xterm-256color означают широкую поддержку, а dumb — минимальную. Возможная причина также в устаревшей версии эмулятора — обновление часто решает проблему.

Третий случай — вывод перенаправлен. Как отмечено выше, в pipe или файл коды попадают в сыром виде. Проверка [ -t 1 ] в Bash — стандартный способ определить, подключён ли stdout к терминалу, и включать раскраску только тогда.

⚠️ Внимание: команда tput формирует последовательности с учётом базы terminfo и текущего TERM, поэтому её вывод надёжнее «зашитых» в скрипт кодов. Для переносимых скриптов предпочитайте tput setaf 1 вместо ручного ESC[31m.
💡

Команда `infocmp` покажет, какие возможности описаны в базе terminfo для вашего значения TERM — полезно при отладке неработающих кодов.

Безопасность и ограничения

Escape-последовательности — не только инструмент оформления, но и потенциальный вектор проблем. Вредоносный текст, содержащий управляющие коды, может очистить экран, переместить курсор или подменить видимое содержимое при просмотре файла через cat. Поэтому для просмотра непроверенных файлов безопаснее использовать less с флагом -R (который контролирует интерпретацию кодов) или cat -v, показывающий управляющие символы явно.

Также помните, что стандарт не гарантирует одинакового поведения во всех эмуляторах. Одни последовательности (цвета, очистка) поддерживаются практически везде, другие — например, изменение заголовка окна через ESC]0;текст\a или скроллинг областей — реализованы не везде. Если пишете переносимый инструмент, тестируйте вывод минимум в нескольких популярных терминалах.

💡

Надёжная формула переносимого цветного вывода: проверка isatty → использование tput или проверенных SGR-кодов → обязательный сброс ESC[0m.

Частые вопросы

Чем отличаются \033, \x1b и \e?

Это разные записи одного и того же символа ESC (десятичный код 27). Какая форма сработает, зависит от языка или утилиты: \033 и \e понимает echo -e и printf в Bash, \x1b — C и Python, \u001b — Python 3 и JavaScript.

Почему цвета не работают в скрипте через cron?

Задания cron выполняются без подключённого терминала, поэтому переменная TERM обычно не установлена, а stdout не является TTY. Коды либо не интерпретируются, либо записываются в лог как текст. Возможное решение — проверять [ -t 1 ] и отключать раскраску вне терминала.

Как вернуть терминал в норму после «глюка» с кодами?

Выполните команду reset — она переинициализирует терминал. Если пропал только курсор, достаточно printf '\033[?25h'. Если слетели цвета — printf '\033[0m'.

Можно ли использовать коды управления в prompt (PS1)?

Да, но в Bash непечатаемые последовательности нужно оборачивать в \[ и \], иначе оболочка неверно вычислит длину строки приглашения и переносы строк «поедут». Пример: PS1='\[\033[32m\]\u@\h\[\033[0m\]\$ '.

Работают ли ANSI-коды в PowerShell?

В современных версиях PowerShell и Windows Terminal — да, поддержка виртуальных терминальных последовательностей включена. В устаревших версиях консоли Windows поведение может отличаться, поэтому для старых систем сверяйтесь с документацией конкретной версии ОС.