如何同时将字符串输出到变量和控制台

时间:2011-08-17 02:07:35

标签: powershell

在powershell中有一种简单的方法可以同时将字符串输出到变量和控制台吗?

我想将我的脚本输出捕获到变量中,以便我可以在脚本的末尾对其进行分析,将其保存到日志文件中,并通过电子邮件发送给操作员。

我的意图是拥有一个变量$ output并向其添加任何输出字符串,并立即输出到控制台

$output="Process started"

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

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

所以最后我可以将$ output保存到日志文件中,通过电子邮件发送并解析它。

我使用了可能为此目的而工作的tee-object但不幸的是它会重写我的$ output变量而不是为它添加一个字符串。

更新 这是我决定采用的最终解决方案 - 感谢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 个答案:

答案 0 :(得分:6)

有很多方法可以实现最终目标:

在你的脚本中只有这样的东西:

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

然后将脚本作为

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

请注意,Tee-Object可以使用输出,因此控制台可以在发生时使用。只有在整个脚本运行后才能获得输出。这就是管道在Powershell中的工作方式。对象在它们发生时沿着下游传递。在步骤之间插入一个sleep 10,看看输出是否可用。

此外,您不一定要有另一个您正在谈论的脚本(launcher.ps1)。您可以在脚本中使用函数,scriptblock等。

其他一些方式:

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

可能还有很多方法可以做到这一点。

答案 1 :(得分:5)

这是一个很好的技巧,将变量赋值括在括号中。您可以在PowerShell语言规范(第7.1.1节分组括号)中找到更多相关信息,以便下载here

PS > ($var=1)
1
PS >

答案 2 :(得分:1)

我没有充分讨论powershell给出具体答案,但如果我在C中这样做,我会利用副作用。

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

使用如下功能:

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

它会产生预期的效果。 (抛开正确的C语法和迂腐,例如处理换行符)我不知道如何将它转换为powershell。

但是,您想要做的事情可能会被视为混乱。如果您只是显式输出并记录输出并在代码中依次记录,则可能会更清楚。副作用不可避免地会回来咬你。保持模块化。

答案 3 :(得分:1)

我正在寻找与此相似的东西,除了之后我不需要分析它,只收集输出。

其他人可能会看到的东西,因为看起来你有答案是使用PowerShell成绩单(Start-Transcript和Stop-Transcript)。我从这个site发现当你点击服务器时它确实有一些问题错误,但他展示了他是如何处理的。

答案 4 :(得分:0)

要扩展@manojlds答案,您可以简单地使用Tee-Object cmdlet,而不是指定要写入的文件,可以告诉它直接写入变量,如下所示:

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

script / cmdlet / function / etc的所有输出将实时写入控制台屏幕,并在脚本完成运行时存储在$output变量中。这样,您便可以对其进行分析或使用该变量将其写入文件。这样可以避免在操作完成后将文件内容读入变量。

答案 5 :(得分:0)

脚本将在输出屏幕上写入数据,并将相同的数据存储在变量中

get-process | Tee-Object -Variable test

$test can use further 

答案 6 :(得分:-1)

("Process started" | out-host) | Set-Variable x ; $x