2

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

powershell "startmyserver | tee server.log"

Проблема заключается в том, что канал вызывает выполнение первой команды и ее полное выполнение до выполнения второй команды. Это означает, что я не могу контролировать стандартный вывод моего сервера, пока он действительно работает, что я и пытаюсь сделать (я не хочу выключать сервер, чтобы просто проверить самые последние сообщения журнала).

Для более простого примера я попытался сделать pause . Ну, pause в Powershell не существует, поэтому мне пришлось запустить ее во вложенной оболочке cmd :

powershell "cmd /c pause | tee test.txt"

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

То, что я хочу сделать, это канал для потоковой передачи stdout строка за строкой для следующей команды. Другими словами, всякий раз, когда он сталкивается с символом EOL, он должен посылать некоторый вывод, и это должно (в моем случае tee) вызывать появление текста на экране и одновременную запись в файл. (На самом деле, я даже не беспокоюсь о том, записывается ли текст в файл построчно, он может быть записан полностью в конце, хотя это не было бы идеально. Я просто хочу видеть строки на экране в том виде, в котором они написаны.)

Возможно ли это в командной строке и / или в Powershell?

1 ответ1

1

Эта проблема в переполнении стека объясняется тем фактом, что объект PowerShell Tee-Object не сбрасывает поток вывода, а только ожидает, пока источник сделает это, поэтому вы получите вывод в конце операции. Это по замыслу.

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

./program | ForEach-Object {
    Write-Host $_
    $_
} | Set-Content program.log

Альтернативная формулировка, чтобы попытаться, если вышеупомянутый не работал:

./program | ForEach-Object {
    [Console]::WriteLine($_)
    [Console]::Out.Flush()
    $_
} | Set-Content program.log

Таким образом, команда будет выглядеть так:

PowerShell -ExecutionPolicy Unrestricted "startmyserver | ForEach-Object { Write-Host $_; $_} | Set-Content server.log"

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .