как вывести строку в переменную и консоль одновременно - PullRequest
9 голосов
/ 17 августа 2011

Есть ли в PowerShell простой способ вывести строку в переменную и консоль одновременно?

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

Мое намерение состоит в том, чтобы иметь переменную $ output и добавлять в нее любые выходные строки, а также выводить на консоль сразу что-то вроде

$output="Process started"

$output=+"Doing step 1"
"Doing step 1"

$output=+"Doing step 2"
"Doing step 2"

так что в конце я могу сохранить $ output в файл журнала, отправить его по электронной почте и проанализировать.

Я играл с tee-object, который мог бы работать для этой цели, но, к сожалению, он переписал бы мою переменную $ output вместо добавления к ней строки.

UPDATE Это окончательное решение, с которым я решил пойти - благодаря manojlds!

$script:output = ""

filter mylog {
    $script:output+= $_+"`n"
    return $_
}


"doing step {0}" -f 1 | mylog
"doing step {0}" -f 2 | mylog
"doing step {0}" -f 3 | mylog

#in the end of the script
$script:output

Ответы [ 7 ]

6 голосов
/ 17 августа 2011

Есть так много способов получить конечную цель:

В вашем скрипте просто есть что-то вроде этого:

"Process started"
<step1>
"Doing step 1"
<step2>
"Doing step 2"
...

Затем запустите скрипт как

.\test.ps1 | Tee-Object -file log.txt

Обратите внимание, что вывод доступен для Tee-Object и, следовательно, консоли, как и когда это происходит. Вы не получите вывод только после запуска всего скрипта. Так работает конвейер в Powershell. Объекты передаются вниз по течению, как и когда они происходят. Вставьте sleep 10 между шагами и убедитесь, что вывод поступает, как только он становится доступным.

Кроме того, вам не обязательно иметь другой скрипт (launcher.ps1), о котором вы говорите. Вы можете использовать функции, блок скриптов и т. Д. В вашем скрипте.

Некоторые другие способы:

function test {

"Process started"
sleep 5
"Doing step 1"
sleep 5
"Doing step 2"

}

test | %{$output+=$_;$_}
#use output
write-host -fore blue $output

Вы можете создать фильтр:

$script:output = ""

filter appendOutput {

    $script:output+= $_
    return $_
}

"Process started" | appendOutput
sleep 5
"Doing step 1" | appendOutput
sleep 5
"Doing step 2" | appendOutput
#use output
write-host -fore blue $script:output

Возможно, есть еще много способов сделать это.

5 голосов
/ 17 августа 2011

Вот хороший трюк, заключите вашу переменную в скобки.Подробнее об этом вы можете узнать в спецификации языка PowerShell (раздел 7.1.1 Группировка скобок), которую можно загрузить здесь :

PS > ($var=1)
1
PS >
1 голос
/ 17 августа 2011

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

Что-то, на что кто-то может взглянуть, так как кажется, что ваш ответ использует ваш ответСтенограммы PowerShell (Start-Transcript и Stop-Transcript). Я обнаружил на этом сайте , что у него есть некоторые проблемы при попадании на серверную ошибку, но он показывает, как он ее обрабатывал.

1 голос
/ 17 августа 2011

Я не достаточно испортил powershell, чтобы дать конкретный ответ, но если бы я делал это в C, я бы использовал побочные эффекты.

//Psuedo-C
string con (oldString, newString) {
  print(newString);
  return oldString + newString;
}

Используйте функцию так:

myString = con(myString, "Process started");

Это будет иметь желаемый эффект. (оставляя в стороне правильный синтаксис C и педантичность, например, работу с новыми строками) Я не знаю, как перевести это на powershell.

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

0 голосов
/ 04 июля 2019

Скрипт запишет данные на экран вывода, а также сохранит те же данные в переменной

get-process | Tee-Object -Variable test

$test can use further 
0 голосов
/ 18 июля 2018

Чтобы немного расширить ответ @manojlds, вы можете просто использовать командлет Tee-Object, но вместо того, чтобы указывать файл для записи в него, вы можете указать его для записи непосредственно в переменную, например:

.\test.ps1 | Tee-Object -Variable output

Все выходные данные скрипта / командлета / функции / etc будут записаны на экран консоли в режиме реального времени, а также сохранены в переменной $output, когда скрипт завершит работу. Таким образом, вы можете проанализировать его или записать в файл, используя эту переменную. Это избавит вас от необходимости читать содержимое файла в переменную после завершения операции.

0 голосов
/ 17 августа 2011
("Process started" | out-host) | Set-Variable x ; $x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...