Что такое…

Что такое TTY — и почему программа молчит, когда вывод уходит в файл

Иллюстрация: старый телетайп печатает ленту, а рядом машина у глухой трубы замерла с поднятой рукой

Ты запускаешь скрипт на Python. Он печатает прогресс: «обработано 1», «обработано 2»… Всё живо.

Теперь хочешь сохранить вывод в лог и пишешь python job.py | tee job.log. И экран пустой. Минуту. Пять. Ты уже уверен, что скрипт завис. А потом он вываливает все строки разом — и завершается.

Скрипт не зависал. Он просто понял, что на него больше не смотрит человек. Программы умеют это проверять. И проверка называется TTY.

Что такое TTY

TTY — сокращение от teletypewriter, телетайп. Сто лет назад это была печатная машинка, соединённая проводом с другой такой же. Позже к компьютерам подключали телетайпы как экран и клавиатуру. Отсюда и название.

Телетайпов давно нет, а слово осталось. Сегодня TTY — это «живой» терминал: окно, где сидит человек, видит вывод и может что-то нажать. Твой терминал — это TTY. А файл, пайп, лог в CI — нет.

Любая программа может спросить у системы: «мой вывод сейчас идёт в TTY?» Проверь сам:

[ -t 1 ] && echo "человек смотрит" || echo "вывод уходит в трубу"

Запусти так, а потом с | cat в конце. Ответ поменяется. Единица здесь — номер потока stdout, про потоки вывода есть отдельный разбор.

Что программы делают по-другому без TTY

Как только человек «пропал», многие инструменты меняют поведение. Специально, из лучших побуждений:

  • Цвета исчезают. ls, grep, git и тесты не красят вывод, чтобы в лог не попал мусор вроде ^[[31m.
  • ls пишет в один столбец. В терминале — сетка, в пайпе — по файлу на строку. Так удобнее следующей команде.
  • git log не открывает листалку. В терминале он показывает историю постранично, в пайпе отдаёт всё сразу.
  • Python копит вывод. Это наш случай. Для человека Python печатает построчно. Для трубы — собирает в буфер по несколько килобайт и выдаёт пачкой. Быстрее, но для тебя выглядит как зависание.

Лечится одной настройкой:

python -u job.py | tee job.log
# или
PYTHONUNBUFFERED=1 python job.py | tee job.log

Флаг -u выключает буфер. Строки снова пойдут сразу. Та же беда бывает у grep в середине пайпа, у него есть флаг --line-buffered.

Что без TTY вообще не работает

Есть программы, которым нужен человек на том конце. Без TTY они падают или ждут вечно:

  • sudo не может спросить пароль: a terminal is required to read the password.
  • docker exec -it в CI падает с ошибкой the input device is not a TTY. Буква t в -it просит терминал, а в CI его нет. Убери t, оставь -i.
  • Интерактивные мастера вроде npm init, git rebase -i или вопроса «Продолжить? (y/n)» ждут ответа, которого никто не даст.

Как понять, что странность именно из-за TTY? Простой тест: запусти команду как обычно, а потом ту же с | cat в конце. Если поведение поменялось — пропали цвета, вывод пришёл пачкой, исчез вопрос — дело в TTY. Если ничего не поменялось, ищи причину в другом месте.

А если программе позарез нужен терминал, а его нет? В Linux есть команда script, она подсовывает поддельный TTY: script -q -c "npm test" /dev/null. Программа думает, что на неё смотрит человек, и ведёт себя как в окне. Пользуйся редко: обычно правильнее найти флаг вроде --yes.

Зачем это тебе, если команды запускает ИИ

Агенты вроде Claude Code и Codex выполняют команды без TTY. Они читают вывод как текст из трубы, а не смотрят в окно.

Отсюда три вещи, которые ты заметишь:

  1. В логах агента нет цветов, а ls выглядит списком. Это нормально.
  2. Команда, которая ждёт ответа «y/n», может повесить агента. Поэтому хорошие агенты добавляют --yes, -y или CI=true. Если видишь, что агент застрял на установке — проверь, не задала ли она вопрос.
  3. Python-скрипт, запущенный агентом, «молчит» до конца. Попроси добавить -u — и прогресс станет видно.

Тот же расклад в CI/CD: сборка на сервере — это тоже мир без TTY.

Как заставить цвета работать в пайпе?

У большинства инструментов есть флаг --color=always, например grep --color=always error log | less -R. Многие Node-утилиты понимают переменную FORCE_COLOR=1.

Что такое /dev/tty и pts?

Это имена TTY в системе. Команда tty покажет твоё, например /dev/pts/0. «pts» значит псевдотерминал: окно терминала, которое притворяется старым телетайпом.

Почему ssh иногда пишет «Pseudo-terminal will not be allocated»?

Ты передал ssh команду или вход из пайпа, и он решил, что терминал не нужен. Если удалённая команда интерактивная, добавь флаг -t.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение
Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →