Трійник не отримує весь вихід з труби


12

У мене є сценарій виконання команд, таких як:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;./some_app -i $INDEX | tee $LOG
echo "Number of errors: $(grep "ERROR" $LOG | wc -l)"

Проблема, ймовірно, в тому, що потрібно tee. Здається, не виходить весь вихід. Коли програма закриває останні кілька рядків виводу (зазвичай ті, що містять фатальну помилку), відсутні. Коли я запускаю додаток без труби, teeя отримую їх у висновку.

Як змусити скрипт чекати, коли трійник завершить обробку всіх вихідних даних?


Це працює добре, якщо ви підключите його до файлу, а не stdout?
Пілот6

Відповіді:


23

Фатальна помилка, ймовірно, виходить у STDERR (2), а не STDOUT (1). Ви можете перенаправити STDERR в STDOUT за допомогою, 2>&1і тоді труба також повинна захопити його.

./some_app -i $INDEX 2>&1 | tee $LOG

Якщо у вас є проблеми з буферизацією зверху, ви можете перевести їх у нерозподілений стан:

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG

Добре, ми все ближче. Тепер я бачу, що фатальна помилка друкується, але знову ж таки не є повною. Рядок з помилкою просто закінчується посередині, і вихід ехо продовжується. Існує проблема з буфером для промивання або просто очікуванням завершення цієї частини.
Ladislav Mrnka

Відредаговано. Досить рідкісний в моєму досвіді, що щось так повністю проскакує через буфери на виході, але варто йти.
Олі

1
Готово! Дякую. Я можу задати занадто багато запитань, але хтось розуміє, чому мені потрібно вимкнути буферизацію під час передавання в інший процес?
Ладислав Мрнка

@Oli Дуже хороший!
Пілот6

6

Оскільки повідомлення про помилки зазвичай відображаються на STDERR (Дескриптор файлу 2), вам потрібно перенаправити і STDOUT, і STDERR на tee:

./some_app -i "$INDEX" |& tee "$LOG"

Коли ви робите, ./some_app -i $INDEX | tee $LOGви переспрямовуєте лише STDOUT на tee.

|& призведе до переадресації і STDOUT, і STDERR.

Якщо ви не можете переспрямувати лише STDOUT (як і раніше):

./some_app -i "$INDEX" | tee "$LOG"

З іншого боку, якщо ви хочете переспрямувати лише STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.