proc
Все процессы из Procfile в одном терминале, каждый в своём PTY.
Ещё один запускатель Procfile. foreman делает это больше десяти лет и делает хорошо — мне хотелось такой, который не мешается, когда процесс ведёт себя плохо. И я умею такие писать.
Один бинарник. Кладёшь Procfile в папку, запускаешь proc — и стартует каждая его строчка:
db: postgres -D ./tmp/db
web(delay:2s): bin/rails server
worker(restart, retries:5): bundle exec sidekiq
seed(optional, once, allow-failure): bin/rails db:seed
Каждый процесс получает свой PTY, а не пайп. В этом решении почти весь смысл и есть: программа, которая проверяет isatty, ведёт себя ровно так же, как в твоём собственном шелле, — цвета, прогресс-бары и интерактивные приглашения переживают сведение в один поток. Имена красятся обходом круга HSL золотым углом, так что седьмой процесс отличается от шестого настолько же заметно, насколько первый от второго.
В скобках — флаги процесса, и каждый касается только того процесса, который его объявил. once оставляет его лежать после выхода. restart всегда поднимает обратно. stop уводит за собой весь запуск. optional держит его вне запуска, пока не попросят по имени. delay:2s придерживает старт, retries:5 сдаётся после пятой попытки, muted убирает его вывод из терминала, allow-failure означает, что его ненулевой выход не роняет запуск.
В терминале интерактивный режим включён по умолчанию. G открывает поверх потока логов полноэкранное меню: старт, стоп, рестарт, kill, режим выхода для отдельного процесса, добавление процесса в уже идущую сессию, живой ps и дашборд, который раз в секунду снимает память и CPU по всей группе каждого процесса — шелл плюс всё, что он породил, — и рисует историю спарклайнами. У каждого пункта своя буква.
Сессия живёт дольше набора процессов. Пустая таблица — это всё ещё приглашение, в которое можно добавить, а вышедший процесс остаётся в списке, чтобы его можно было поднять снова. Явный стоп старше политики --on-exit: то, что ты положил, лежит.
Если на входе пайп, а запускать нечего, он читает stdin и рисует его тем же самым потребителем — так что journalctl -f | proc даёт тот же цветной поток с таймстампами. Имена процессов считаются просьбой запустить и перевешивают пайп: именно поэтому proc web работает из скрипта и из CI, где stdin никогда не терминал.
Где заканчивается. Только Unix: PTY и сигналы — это весь механизм, сборки под Windows нет. Счётчик потоков в дашборде работает только на Linux, потому что больше нигде sysinfo его не отдаёт, а число открытых дескрипторов по процессу непортируемо вовсе, так что этой цифры здесь нет.
Ctrl+C посылает SIGINT и ждёт пять секунд перед SIGKILL. Второй Ctrl+C не ждёт.
Rust, MIT. Готовый бинарник под macOS или Linux:
brew install jwo1f/tap/proc
Или сборка из исходников:
cargo install --git https://github.com/JWo1F/proc