Как сохранить новые строки из вывода команды, распечатанные с помощью Write-Host в Powershell?

Недавно (2-3 дня назад) я начал использовать Powershell. У меня есть приложение на C++, которое использует argparse для обработки некоторых аргументов командной строки. Если что-то не так, как ожидалось, мой код завершается со строкой справки, предоставленной флагом -/--help любого приложения, использующего эту библиотеку.

Я использую (вывод $PSVersionTable):

Name                           Value
----                           -----
PSVersion                      5.1.19041.2364
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.2364
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

У меня есть файл конфигурации CMake

Write-Host "${APP_NAME} (${BUILD_TYPE})"

$model = ""
$data_in = ""

Write-Host "Checking input arguments"
if ($args.count -ne 5)
{
    Write-Host "Found {0} arguments but expecting 5" -f $args.count
    Write-Host $(./pytorch_load_model.exe --help) -foregroundcolor Cyan
    exit
}

for ( $i = 0; $i -lt $args.count; $i++ ) {
    if (($args[ $i ] -eq "-m") -or ($args[ $i ] -eq "--model")){ $model=$args[ $i+1 ]}
    if (($args[ $i ] -eq "-i") -or ($args[ $i ] -eq "--input")){ $data_in=$args[ $i+1 ]}
}

$fail = $false
if ($model -eq "")
{
    Write-Host "No path for model provided"
}
if ($data_in -eq "")
{
    Write-Host "No path for input provided"
}
if ($fail -eq $true)
{
    Write-Host (./model.exe --help)
    exit
}

# TODO Add check if $opencv and $libtorch valid dir paths
$opencv = "${OPENCV_BIN}"
$libtorch = "${LIBTORCH_BIN}"
#$model = "${PTH_MODEL_PATH}"
#$input = "${INPUT_IMG_PATH}"
Write-Host "Executing model"
$env:Path = "$($env:Path);$($opencv);$($libtorch)"; ./pytorch_load_model.exe -m "$($model)" -i "$($data_in)"

который обрабатывается с помощью configure_file() для вывода скрипта (*.ps1 файла), который добавляется в двоичный каталог моего проекта (EXE, dlls и другие данные, относящиеся к времени выполнения). Он настраивает PATH так, что приложение работает как положено, а также передает тот же аргумент командной строки, что и мое приложение.

Я заметил, что Write-Host «съедает» все новые строки, которые появляются в виде многострочной строки из моего приложения.

Вместо

PyTorch Load Model (release)
Checking input arguments
Usage: model [--help] [--version] [--model-path VAR] [--png-path VAR]

Optional arguments:
  -h, --help        shows help message and exits
  -v, --version     prints version information and exits
  -m, --model-path  Path to PTH TorchScript model
  -i, --png-path    Path to PNG image to be processed by the model

я получаю

Usage: model [--help] [--version] [--model-path VAR] [--png-path VAR]  Optional arguments:   -h, --help        shows help message and exits    -v, --version     prints version information and exits    -m, --model-path  Path to PTH TorchScript model    -i, --png-path    Path to PNG image to be processed by the model

Как сохранить новые строки?

вы используете PowerShell 5.1 или 7.x? Скорее всего это кодирование махинаций из приложения cmd.exe в Powershell

sirtao 20.08.2024 12:21

@sirtao Я добавил информацию в ОП.

rbaleksandar 20.08.2024 12:33

Направьте вывод на хост записи: (./model.exe --help) | хост записи

nimizen 20.08.2024 13:22
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Как предполагает @nimizen, лучшим вариантом будет трубопровод: (./model.exe --help) | write-host

В качестве альтернативного решения вы можете использовать ((./model.exe --help) -join "`r`n")

Вместо Write-Host вы можете использовать Write-Output, который просто передает значения в выходной поток. В то время как Write-Host превращает данные только в вывод на экран, и если вы не меняете цвета шрифта, это никогда не понадобится.

Тоже хороший вариант, хотя хотелось бы использовать раскраску. :D

rbaleksandar 20.08.2024 18:00

Полезный ответ Сиртао показывает эффективные решения.


Что касается того, что вы пробовали:

  • Когда PowerShell вызывает внешнюю программу, она построчно передает выходные данные стандартного вывода в конвейер PowerShell.

  • При заключении такого вызова в (...) — например, для передачи вывода в качестве аргумента команды, как в этом случае — строки обязательно собираются в массив (типа [object[]]), при условии, что существует две или более строк.

  • Write-Host, если в качестве аргумента передан массив, печатает (строчные) элементы массива в одной строке, каждый из которых разделен одним пробелом — вот что вы видели:

    • Простой пример:

      # -> 'foo bar'
      Write-Host @('foo', 'bar')
      
    • Чтобы добиться многострочного вывода (оба метода показаны в ответе Сиртао):

      • Либо: предоставьте выходные данные, полученные в результате вызова внешней программы (например, ./model.exe --help) через конвейер , который заставляет Write-Host печатать каждый входной объект конвейера в отдельной строке.

      • Или: Явно соедините строки, выводимые внешними программами, с символами новой строки, чтобы сформировать одну многострочную строку, которая Write-Host печатается как есть.

        • В качестве альтернативы решению -join в ответе Сиртао вы можете использовать командлет Out-String; например.:

           Write-Host -NoNewLine (./model.exe --help | Out-String)
          
          • Обратите внимание на использование -NoNewLine, которое компенсирует тот досадный факт, что Out-String добавляет завершающую новую строку к создаваемой многострочной выходной строке; это проблемное поведение обсуждается в выпуске GitHub № 14444.

Дополнительное чтение: Соответствующее использование Write-Host для создания цветного вывода stderr:

Отличное объяснение, очень полезно

sirtao 21.08.2024 10:09

Рад это слышать, @sirtao; Я ценю приятный отзыв.

mklement0 21.08.2024 12:47

Другие вопросы по теме