Я изучил почти все доступные подобные вопросы , но безрезультатно.
Позвольте мне подробно описать проблему:
Я запускаю несколько автоматических сценариев, и они могут генерировать стандартный вывод и стандартные строки ошибок, я хочу записать их в точном порядке, отображаемом эмулятором терминала, а затем добавить к ним префикс, такой как «STDERR:» и «STDOUT:».
Я пытался использовать трубы и даже основанный на эполле подход к ним, но безрезультатно. Я думаю, что решение находится в pty использовании, хотя я не мастер в этом. Я также заглянул в исходный код VTE Gnome , но это не было очень продуктивным.
В идеале я бы использовал Go вместо Bash для этого, но я не смог. Похоже, что трубы автоматически запрещают поддерживать правильный порядок строк из-за буферизации.
Кто-нибудь смог сделать что-то подобное? Или это просто невозможно? Я думаю, что если эмулятор терминала может это сделать, то это не так - может быть, путем создания небольшой программы на C, которая по-разному обрабатывает PTY?
В идеале я хотел бы использовать асинхронный ввод для чтения этих двух потоков (STDOUT и STDERR), а затем перепечатывать их, как мне нужно, но порядок ввода имеет решающее значение!
ПРИМЕЧАНИЕ: я знаю о stderred, но он не работает для меня со сценариями Bash и не может быть легко отредактирован для добавления префикса (поскольку он в основном содержит множество системных вызовов).
Обновление: добавлено ниже двух гист
- Пример программы, которая генерирует смешанный stdout / stderr
- Ожидаемый результат от программы выше
(случайные задержки в секунду могут быть добавлены в пример сценария, который я предоставил, чтобы доказать непротиворечивый результат)
Обновление: решение этого вопроса также решило бы этот другой вопрос , как отметил @Gilles. Однако я пришел к выводу, что невозможно делать то, что просили здесь и там. При использовании 2>&1
оба потока корректно объединяются на уровне pty / pipe, но чтобы использовать потоки отдельно и в правильном порядке, действительно следует использовать подход stderred, который включает перехват системных вызовов и может рассматриваться как грязный во многих отношениях.
Я буду стремиться обновить этот вопрос, если кто-то может опровергнуть вышеизложенное.