Терминал

Терминальные хосты выполняют Lua-скрипты с доступом к stdin/stdout/stderr.

Терминальный хост запускает ровно один процесс за раз. Сам процесс — обычный Lua-процесс с доступом к контексту терминального ввода-вывода.

Тип записи

Тип Описание
terminal.host Хост терминальной сессии

Настройка

- name: cli_host
  kind: terminal.host
  hide_logs: false
  lifecycle:
    auto_start: true
Поле Тип По умолчанию Описание
hide_logs bool false Скрыть вывод логов в шину событий

Контекст терминала

Скрипты, работающие на терминальном хосте, получают терминальный контекст с:

  • stdin — чтение стандартного ввода
  • stdout — запись в стандартный вывод
  • stderr — запись в стандартный поток ошибок
  • args — аргументы командной строки

Композируемые терминалы

Терминал, который видит процесс, — это порт, а не устройство. Благодаря этому владение терминалом становится композируемым.

Процесс на терминальном хосте владеет физическим портом. Он вызывает tty.surface(), чтобы взять аренду представления порта, и публикует целые кадры — он владеет всем экраном.

Процесс-оболочка размещает у себя другие процессы, создавая виртуальные терминалы через tty.viewport(). Он передаёт viewport:grant() дочернему процессу через опцию spawn terminal; дочерний процесс превращает этот грант в обычный терминальный порт и работает без изменений, не зная, что не подключён к устройству. Оболочка читает кадры дочернего процесса через viewport:snapshot(), размещает их где угодно в собственной компоновке и транслирует ввод в координаты дочернего процесса через viewport:send().

local view = assert(tty.viewport({width = 78, height = 20}))
local child = assert(process.with_options({terminal = assert(view:grant())})
    :spawn_monitored("app:child", "app:workers"))

Грант одноразовый: допуск процесса потребляет его, отклонённый запуск оставляет его неразрешённым, а хост, не умеющий присоединять терминалы, отклоняет spawn, а не игнорирует опцию.

Байт-ориентированные программы включаются в ту же модель через exec. Дочерний процесс выделяет PTY-процесс и вызывает process:attach_terminal(); этот адаптер владеет эмуляцией PTY, кодированием ввода, изменением размера и завершением и выводит на тот порт, которым владеет дочерний процесс, — физический или виртуальный.

physical terminal -> shell surface -> viewport -> child process -> PTY proxy

Lua API

Модуль IO предоставляет построчные терминальные операции:

local io = require("io")

io.write("Введите имя: ")
local name = io.readline()
io.print("Привет, " .. name)

local args = io.args()

Функции возвращают ошибку при вызове вне терминального контекста.

Про события сырого ввода, стилизованный рендеринг, surface и viewport см. TTY. Про PTY-процессы и терминальные сессии см. Выполнение команд.

См. также

  • Terminal I/O — операции stdin/stdout/stderr
  • TTY — события ввода, surface, canvas и viewport
  • Выполнение команд — PTY-процессы и терминальные сессии
  • Terminal UI — сборка оболочки, размещающей дочерний процесс в viewport