передача long stdout в команду tee иногда приводит к усечению - PullRequest
4 голосов
/ 26 октября 2019

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

первый пример:
seq 50000|tee >(wc) >(head -2) >/dev/null
выведет:

                1
                2
  12773   12774   65536

вместо

                1
                2
  50000   50000  288894

второй пример:
cat f.txt|grep abc|tee f.txt >/dev/null
в этом примере обновление файла будет работать, только если файл короткий, но если файл длинный, иногда tee начинает запись до завершения cat, и обновление файла будет работать только на первомпереход 'cat'.

Вы можете сказать, что tee предназначен только для перенаправления на файлы, но я также вижу, что использование tee.
Я знаю, что команда pee не имеет этой ошибки, но кто-то знаетобходной путь, чтобы заставить тройник ждать?
спасибо: -)

1 Ответ

5 голосов
/ 26 октября 2019

Проблема, с которой вы столкнулись, может быть сведена к следующему:

seq 50000 | tee >(wc) >(exit) >/dev/null

Если один из потоков tee пишет, что возвращает ошибку, tee завершается. Поскольку каналы обычно буферизуются буфером 4K, для wc достаточно захватить некоторые строки и обработать их.

head -n2 закрывает поток после печати двух строк.

Вы можете видетьошибка, сказав tee что-то напечатать при ошибках:

# seq 50000 | tee --output-error=exit >(wc) >(exit) >/dev/null
tee: /dev/fd/62: broken pipe

Вы можете устранить проблему с помощью -p или --output-error=warn, чтобы указать tee продолжить после ошибок при записи в каналы:

seq 50000 | tee -p >(wc) >(head -n2) >/dev/null

или используйте команду, которая не завершается после обработки ввода, например sed:

seq 50000 | tee >(wc) >(sed -n '1,2p') >/dev/null
...