如何在 PowerShell 中输出内容

How to output something in PowerShell

提问人:Pekka 提问时间:1/11/2010 最后编辑:SquashmanPekka 更新时间:10/4/2021 访问量:745954

问:

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

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

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

在 PowerShell 脚本中,如果返回值不是“OK”,我想从网站输出返回值,因此错误消息将包含在控制台输出中,从而包含在状态邮件中。

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

  • 写主机
  • 写输出
  • 写入错误

使用什么来写入 Windows 等效项是正确的?stdout

Windows PowerShell的

评论


答:

8赞 GrayWizardx 1/11/2010 #1

您可以在方案中使用其中任何一个,因为它们写入默认流(输出和错误)。如果要将输出通过管道传递到另一个 commandlet,则需要使用 Write-Output,它最终将在 Write-Host 中终止。

本文介绍不同的输出选项: PowerShell O 用于输出

评论

1赞 Pekka 1/11/2010
谢谢你的链接。天哪,这很复杂。如果 Write-host 是某种端点或刷新功能,我将尝试使用它并报告。
143赞 naivists 1/11/2010 #2

我认为在这种情况下,您将需要 Write-Output

如果你有一个像这样的脚本

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

然后,如果您使用重定向输出调用脚本,例如 ,您将在“out.txt”中进入屏幕。yourscript.ps1 > out.txttest2test1\ntest3\n

请注意,“test3”和 Write-Output 行将始终在文本中附加一个新行,PowerShell 中没有办法阻止这种情况(也就是说,在 PowerShell 中使用本机命令是不可能的)。如果你想要(在 Bash 中有点基本和简单)功能,那么请看 samthebest 的答案echo -necho -n

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

235赞 Goyuix 1/12/2010 #3

简单地说,PowerShell 是一件美的事情,也是它最大的优势之一。例如,常见的 Hello, World!应用程序简化为一行:

"Hello, World!"

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

其他命令特定于将文本输出到其关联的流,并具有其位置。Write-*

评论

12赞 Joey 2/2/2017
事实并非如此。它是一个字符串文字表达式,也是其管道中唯一的表达式。因此,它等价于 . 另一方面,将对象发送到 PowerShell 主机进行显示,其实现依赖于主机。控制台主机确实将它们发送到标准输出句柄(沿途传递)。但是,PowerShell ISE 会在其输出窗格中显示它们,而其他主机可能会完全执行其他操作。"Hello, World!" | Out-HostOut-HostOut-Default
6赞 Joey 2/2/2017
对象也不会盲目地转换为字符串,而是通过格式化程序来决定如何处理它们。这就是为什么你会看到 的输出以表格形式出现,例如,而具有许多属性(例如 WMI)的结果默认为。Get-ChildItemFormat-List
2赞 samthebest 8/10/2012 #4

你根本无法让 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:\>

评论

0赞 Nicholi 12/29/2012
您可以在 powershell 本身中执行此操作。[System.Console]::Write(“stringy”) 但是,您将无法在 powershell 中重定向它。
2赞 Slogmeister Extraordinaire 3/5/2016
当然可以。看到这个问题
4赞 jordan 2/3/2015 #5
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta

Magenta 可以是“System.ConsoleColor”枚举器值之一 - Black、DarkBlue、DarkGreen、DarkCyan、DarkRed、DarkMagenta、DarkYellow、Gray、DarkGray、Blue、Green、Cyan、Red、Magenta、Yellow、White。

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

18赞 sam-6174 1/16/2016 #6

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

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

评论

1赞 not2qubit 12/8/2018
我可以整天看这个......但为什么只有印刷而不是印刷呢?$x = test123456
0赞 Tony 9/6/2021
Write-Output(或 echo)将指定的对象写入管道。如果 Write-Output 是管道中的最后一个命令,则对象将显示在控制台中。这里是倒数第二个,是否被管道传输到 return 语句并添加了数组 learn.microsoft.com/en-us/powershell/module/......
8赞 mklement0 10/6/2019 #7

使用什么来写入 Windows 等效的 stdout?

实际上,但非常不幸的是从 v7.2 开始,Windows PowerShell 和 PowerShell Core 在通过 PowerShell 的 CLI 从外部调用时,都会将其所有 6(!) 输出流发送到 stdout

  • 请参阅 GitHub 问题 #7989 讨论此有问题的行为,该行为可能不会得到修复,以保持向后兼容性。

  • 在实践中,这意味着将输出发送到的任何 PowerShell 流都将被视为外部调用方的 stdout 输出:

    • 例如,如果从 运行以下命令,则不会看到任何输出,因为 stdout 重定向同样适用于所有 PowerShell 流:cmd.exeNUL

      • C:\>powershell -noprofile -command "Write-Error error!" >NUL
    • 但是,奇怪的是,如果重定向 stderr,PowerShell 将其错误流发送到 stderr,以便您可以有选择地捕获错误流输出;以下输出只是 - 成功流输出 - 同时捕获文件中的错误流输出:2>'hi'err.txt

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

理想的行为是:

  • 将 PowerShell 的成功输出流(数字 1)发送到 stdout

  • 将所有其他流的输出发送到 stderr,这是唯一的选择,因为在进程之间只存在 2 个输出流 - stdout(标准输出)用于数据,stderr(标准错误)用于错误消息所有其他类型的消息(例如状态信息),这些消息不是数据

  • 建议在代码中进行这种区分,即使它目前没有得到尊重


在 PowerShell 内部

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

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

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

  • Write-Error 用于将非终止错误写入错误流(数字);从概念上讲,错误流等同于 stderr。2

  • Write-Output 写入成功 [output] 流 (number ),这在概念上等同于 stdout;它是要将数据(结果)写入的流。1

    • 但是,由于 PowerShell 的隐式输出功能很少需要显式使用 Write-Output
      • 任何未显式捕获、禁止或重定向的命令或表达式的输出都会自动发送到成功流;例如,和是等价的,后者不仅更简洁,而且更快。Write-Output "Honey, I'm $HOME""Honey, I'm $HOME"
      • 有关详细信息,请参阅此答案