У меня проблемы с Perl в Windows (как ActivePerl, так и Strawberry), при перенаправлении скрипта STDOUT на канал и использовании функции sleep(). Попробуйте следующее:Перл STDOUT перенаправлен на канал, нет выхода после вызова sleep()
perl -e "for (;;) { print 'Printing line ', $i++, \"\n\"; sleep(1); }"
Это работает как ожидалось. Теперь труба его тройник (или какой-то файл, такой же результат):
perl -e "for (;;) { print 'Printing line ', $i++, \"\n\"; sleep(1); }" | tee
Там нет никакого вывода вообще, тройник не захватывает ничего. Тем не менее, perl-скрипт все еще запущен, только ничего нет в STDOUT, пока скрипт не завершится, а затем весь вывод будет сбрасываться в tee. Кроме того, если буфер STDOUT заполняет сценарий, он может зависать.
Теперь, если вы удалите сон (звонок), труба работает, как ожидалось! Что происходит?
Я нашел обходное решение; отключение буферизации STDOUT с помощью $ | = 1 заставляет трубу работать при использовании сна, но ... почему? Может ли кто-нибудь объяснить и предложить лучшее решение?
Где ваша программа 'tee'? и что вы подразумеваете под «может повесить»? ты его повесил? – ysth
Я попробовал два разных бинарных файла GNU tee, и даже третий из них был разработан на C# в том же поведении. Кроме того, просто перенаправление на файл с «>» дает такое же поведение. Без сна все в порядке, после этого нет выхода до завершения скрипта. И да, у нас есть сценарии, которые работают весь день, и мы возвращаемся, чтобы найти их подвешенными. – Zybex
Единственное, что изменяет 'sleep', заключается в том, что ваш скрипт не заканчивается немедленно и, следовательно, его буфер сброшен. Это не имеет никакого отношения к «ти». Тем не менее, я также испытал, что приложения с постоянным выходом страдают от буферизации. В нашем случае ОС продолжала буферизацию так долго, ожидая уменьшения объема вывода, что, когда он, наконец, должен был скрыться и «синхронизироваться», он часто занимает слишком много времени, и буфер переполняется, потому что выход остается высоким. Мы вынудили синхронизацию каждые 4 минуты, чтобы исправить это. '$ | = 1' может не исправить это, вам, возможно, придется называть' sync' периодически. – DeVadder