Я пытаюсь захватить вывод из tail в режиме следования, где он выводит текст при обнаружении изменений длины файла - особенно полезно для отслеживания файлов журнала по мере добавления строк. По какой-то причине мой вызов StandardOutput.Read () блокируется до полного завершения работы tail.exe.
Соответствующий пример кода:
var p = new Process() {
StartInfo = new ProcessStartInfo("tail.exe") {
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = "-f c:\\test.log"
}
};
p.Start();
// the following thread blocks until the process exits
Task.Factory.StartNew(() => p.StandardOutput.Read());
// main thread wait until child process exits
p.WaitForExit();
Я также пробовал использовать поддержку обработчика событий OutputDataReceived
, который демонстрирует такое же поведение блокировки:
p.OutputDataReceived += (proc, data) => {
if (data != null && data.Data != null) {
Console.WriteLine(data.Data);
}
};
p.BeginOutputReadLine();
У меня есть немного больше кода вокруг вызова StandardOutput.Read (), но это упрощает пример и по-прежнему демонстрирует нежелательное поведение блокировки. Могу ли я что-то сделать, чтобы мой код реагировал на доступность данных в потоке StandardOutput до выхода из дочернего приложения?
Возможно, это просто причуда того, как работает tail.exe? Я использую версию 2.0 скомпилирован как часть пакета UnxUtils.
Обновление: это, по-видимому, хотя бы частично связано с причудами в tail.exe. Я взял двоичный файл из проекта GnuWin32 как часть пакета CoreUtils, и версия поднялась до 5.3.0. Если я использую опцию -f
для выполнения без повторных попыток, я получаю ужасную проблему «плохой файловый дескриптор» в STDERR (которую легко игнорировать), и процесс немедленно завершается. Если я использую параметр -F
для включения повторных попыток, кажется, что он работает правильно после того, как пришло сообщение о неверном дескрипторе файла и он пытается открыть файл во второй раз.
Возможно, есть более свежий Сборка win32 из репозитория coreutils git. Я мог бы попробовать?