如何在PowerShell中输出一些东西

我正在批处理文件中运行PowerShell脚本。该脚本获取一个网页,并检查页面的内容是否是字符串“OK”。

PowerShell脚本向批处理脚本返回错误级别。

批处理脚本由FTP自动化程序ScriptFTP执行。如果发生错误,我可以让ScriptFTP通过电子邮件将完整的控制台输出发送给管理员。

在PowerShell脚本中,我希望输出来自网站的返回值,如果它不是“OK”,那么错误消息将包含在控制台输出中,从而包含在状态邮件中。

我是PowerShell的新手,不确定要使用哪个输出函数。我可以看到三个:

  • Write-Host
  • 写输出
  • 写错误

用什么东西来写入Windows中的stdout是正确的?

693367 次浏览

您可以在您的场景中使用其中任何一种,因为它们写入默认流(输出和错误)。如果你要将输出输送到另一个命令集,你会想要使用写输出,它最终将在Write-Host中终止。

本文描述了不同的输出选项

我认为在这种情况下,你将需要写输出

如果你有一个脚本

Write-Output "test1";
Write-Host "test2";
"test3";

然后,如果你调用带有重定向输出的脚本,比如yourscript.ps1 > out.txt,你将在“out.txt”中得到屏幕上的test2

请注意,"test3"和Write-Output行将始终附加一个新行到您的文本中,在PowerShell中没有办法停止这一点(也就是说,在PowerShell中,使用本机命令echo -n是不可能的)。如果你想要(在Bash中有点基本和简单)echo -n的功能,那么请参阅samthebest的回答

如果批处理文件运行PowerShell命令,它很可能捕获Write-Output命令。我曾与系统管理员“长时间讨论”什么应该写入控制台,什么不应该写入控制台。我们现在已经同意,脚本执行成功或死亡的唯一信息必须是Write-Host'ed,而脚本作者可能需要知道的关于执行的所有信息(更新了哪些项,设置了哪些字段,等等)都将转到Write-Output。这样,当你向系统管理员提交一个脚本时,他可以很容易地runthescript.ps1 >someredirectedoutput.txt并在屏幕上看到,如果一切正常。然后将“someredirectedoutput.txt”发送回开发人员。

简单地输出一些东西就是PowerShell是一件美丽的事情——也是它最大的优势之一。例如,常见的Hello, World!应用程序简化为一行:

"Hello, World!"

它创建一个字符串对象,赋值给前面提到的值,作为命令管道上的最后一项,它调用.toString()方法并将结果输出到STDOUT(默认情况下)。一件美丽的事情。

其他Write-*命令专门用于将文本输出到相关的流中,并具有相应的位置。

您根本无法让PowerShell提交这些讨厌的换行符。没有脚本或cmdlet可以做到这一点。

当然Write-Host完全是胡说八道,因为你不能从它重定向/管道!你只需要自己写:

using System;


namespace WriteToStdout
{
class Program
{
static void Main(string[] args)
{
if (args != null)
{
Console.Write(string.Join(" ", args));
}
}
}
}

如。

PS C:\> writetostdout finally I can write to stdout like echo -n
finally I can write to stdout like echo -nPS C:\>
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta

洋红色可以是“系统”之一。ConsoleColor”枚举值-黑色,深蓝色,深绿色,暗青色,暗红色,暗品红,暗黄色,灰色,暗灰色,蓝色,绿色,青色,红色,品红,黄色,白色。

+ $File.FullName是可选的,它显示了如何将变量放入字符串中。

我认为下面是Echo vs. Write-Host的一个很好的展示。请注意test()实际上是如何返回一个整数数组,而不是一个整数,因为人们很容易相信。

function test {
Write-Host 123
echo 456 # AKA 'Write-Output'
return 789
}


$x = test


Write-Host "x of type '$($x.GetType().name)' = $x"


Write-Host "`$x[0] = $($x[0])"
Write-Host "`$x[1] = $($x[1])"

上述终端输出:

123
x of type 'Object[]' = 456 789
$x[0] = 456
$x[1] = 789

用什么东西来写入Windows的标准输出是正确的?

效果,但非常不幸,当调用从外部,通过PowerShell的CLI时都是Windows PowerShell和PowerShell核心作为v7.2,发送所有的6(!)输出流stdout

  • 参见GitHub issue #7989关于这个有问题的行为的讨论,这可能不会得到修复,以保持向后兼容性。

  • < p > 在实践中,这意味着无论你发送输出到的PowerShell流将被外部调用者视为stdout输出:

    • < p >。,如果你从cmd.exe运行以下命令,你会看到没有输出,因为标准输出重定向到NUL同样适用于所有PowerShell流:

      • C:\>powershell -noprofile -command "Write-Error error!" >NUL
    • 然而——奇怪的是——如果你重定向stderr, PowerShell does发送错误流到stderr,所以使用2>可以选择性地捕获错误流输出;下面的输出只是'hi' -成功流输出-同时捕获文件err.txt中的错误流输出:

      • C:\>powershell -noprofile -command "'hi'; Write-Error error!" 2>err.txt

< em >的< / em >行为是:

  • 发送PowerShell的success output stream (number 1) to stdout

  • 所有其他流stderr发送输出,这是唯一的选项,因为之间的只处理2输出流——数据的stdout(标准输出),错误消息而且的stderr(标准错误)——所有其他类型的消息——比如状态信息——都不是数据

  • < p > 建议在您的代码中进行这种区分,即使目前还没有这样做


< em > < / em > PowerShell内部:

  • Write-Host用于display输出,而绕过成功输出流——因此,它的输出既不能(直接)在变量中捕获,也不能被抑制或重定向。

    • 它最初的目的只是创建用户反馈和创建简单的、基于控制台的用户界面(彩色输出)。

    • 由于之前无法捕获或重定向,PowerShell版本5使Write-Host写入新引入的信息流(编号6),因此从那时起,可以捕获和重定向Write-Host输出。

  • Write-Error表示写入非终止错误到错误流(编号2);从概念上讲,错误流相当于stderr。

  • Write-Output写入success [output] stream .输出信息(数字1),这在概念上等同于stdout;它是流写入数据(结果)。

      然而,由于PowerShell的隐式输出特征:
      • 任何未被显式捕获、抑制或重定向的命令或表达式的输出都将被自动地 发送到成功流;例如,Write-Output "Honey, I'm $HOME""Honey, I'm $HOME"是等价的,后者不仅更简洁,而且更快。
      • 更多信息请参见这个答案