Почему переданная по каналу команда на тройник не сработала должным образом и не вернулась?

# #bash #go #pipe #tee

Вопрос:

У меня есть приложение Go, которое вставляет данные в базу данных, а также пишет что-то для os.Stdout использования пакета logrus . Для каждой вставки в БД в stdout записывается журнал.

Вот команда, которую я использую goapp | tee myfile

Я обнаружил, что goapp правильно вставлял данные в базу данных в течение нескольких часов, НО файл был пуст, и он ничего не показывал в stdout. В какой-то момент он по какой-то причине остановил вставку (я не знаю).

  • Приложение застряло в ожидании буфера stdout или чего-то в этом роде
  • Каким-то образом, возможно, тройник не запустился или разбился

Если tee разбился, почему goapp не разбился при попытке записи в stdout?! Он должен, по крайней мере, получить a SIGPIPE .

Эта команда работала правильно в течение нескольких недель. Это первый раз, когда он так сильно проваливается, и я теряюсь в догадках о причине. Я больше не уверен в использовании stdout с tee, если он ненадежен.

Код go очень прост:

 import "github.com/sirupsen/logrus"  func NewLogger(outputFile *os.File) *logrus.Logger {  var log = logrus.New()  log.Formatter = new(logrus.JSONFormatter)  log.Level = logrus.TraceLevel  log.Out = outputFile  return log } logger := NewLogger(os.Stdout)  for { [...] err = InsertInDatabase(db, databaseArgs) logger.Traceln("inserted in the database") [...] }  

Я что-то пропустил? В чем может быть причина? Тот факт, что данные были вставлены в БД, но не зарегистрированы в stdout, заставляет меня думать, что с трубой и тройником что-то не так.

Комментарии:

1. Я предполагаю, что logrus по умолчанию выводит данные в stderr вместо stdout

2. Это всегда срабатывало, но в тот раз (не стартовый вопрос) строка log.Out = outputFile задает значение вывода os.Stdout .

3. Одним из альтернативных способов избежать tee превращения в дочерний процесс оболочки, но ждать только завершения вашего приложения golang, было бы использовать замену процесса, т. Е. goapp gt; gt;(tee myfile) . В вашей операции есть вероятность, что ваше приложение умерло и tee не было завершено должным образом

4. (оригинальное сообщение)

5. Также еще одна рекомендация — Попробуйте запустить конвейер, set -e; set -o pipefail чтобы одна неудачная команда вышла из всей системы