如何在PowerShell中输出内容


210

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

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

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

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

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

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

编写与Windows等价的东西用的正确方法是stdout什么?

Answers:


196

仅输出某些东西就是PowerShell,这是一件很美的事情-它的最大优点就是。例如,常见的Hello,World!应用程序简化为一行:

"Hello, World!"

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

其他Write-*命令特定于将文本输出到其关联的流,并按原样放置它们。


9
事实并非如此。这是一个字符串文字表达式,并且是其管道中唯一的东西。因此,它等效于"Hello, World!" | Out-HostOut-Host另一方面,将对象发送到PowerShell主机进行显示,其实现取决于主机。Out-Default实际上,控制台主机将它们发送到标准输出句柄(一直传递)。但是,PowerShell ISE会在其输出窗格中显示它们,其他主机可能会完全做其他事情。
乔伊,

5
对象也不会盲目地转换为字符串,而是通过格式化程序来决定如何处理它们。例如,这就是为什么您看到Get-ChildItem的输出是以表格形式出现的,而具有许多属性(例如WMI)的结果默认Format-List改为使用。
乔伊,

120

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

如果您有类似的脚本

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

然后,如果您使用重定向的输出调用脚本(如)yourscript.ps1 > out.txt,则将test2在屏幕test1\ntest3\n上显示“ out.txt”。

请注意,“ test3”和Write-Output行将始终在文本后添加新行,并且PowerShell中无法阻止它(也就是说,echo -n在PowerShell中使用本机命令是不可能的)。如果您想要(在Bash中有些基本和简单的)功能,echo -n请参阅samthebest的答案

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


9

我认为以下是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

我可以整天看看...但是为什么 $x = test只打印123而不是456呢?
not2qubit

7

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

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


1
感谢您的链接。天哪,这很复杂。如果Write-host是某种端点或刷新功能,我将尝试使用它并进行报告。
Pekka 2010年

3
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta

洋红色可以是“ System.ConsoleColor”枚举器值之一-黑色,深蓝色,深绿色,深青色,深红色,深洋红色,深黄色,灰色,深灰色,蓝色,绿色,青色,红色,洋红色,黄色,白色。

+ $File.FullName是可选的,并展示了如何把一个变量到字符串。


2

您根本无法使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:\>

您可以在powershell本身中执行此操作。[System.Console] :: Write(“ stringy”)但是,您将无法完全在Powershell中对其进行重定向。
Nicholi 2012年

1
你当然可以。看到这个问题
Slogmeister Extraordinaire

1

写入Windows等效于stdout的正确方法是什么?

效果,但是很不幸的是,无论是Windows PowerShell和PowerShell核心为V7.0,送所有的6(!)的输出流标准输出时,称为从外面,通过PowerShell的CLI

  • 有关问题行为的讨论,请参见GitHub问题,出于向后兼容性的考虑,该问题可能无法解决。

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

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

      • 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-Host到新引入的信息流(数6),这样以来则能够捕获和重定向Write-Host输出。

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

  • Write-Output写入成功[输出]流(数字1),在概念上等效于stdout;它是向其写入数据(结果)的流。

    • 但是,由于PowerShell的隐式输出功能,很少需要显式使用Write-Output
      • 任何未明确捕获,禁止或重定向的命令或表达式的输出都会自动发送到成功流;例如Write-Output "Honey, I'm $HOME""Honey, I'm $HOME"等效,后者不仅更简洁,而且速度更快。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.