如何在 PowerShell 中输出内容

Posted

技术标签:

【中文标题】如何在 PowerShell 中输出内容【英文标题】:How to output something in PowerShell 【发布时间】:2011-01-03 12:52:11 【问题描述】:

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

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

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

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

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

写主机 写输出 写入错误

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

【问题讨论】:

【参考方案1】:

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

"Hello, World!"

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

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

【讨论】:

实际情况并非如此。它是一个字符串文字表达式,也是其管道中唯一的东西。因此它等价于"Hello, World!" | Out-Host。另一方面,Out-Host 将对象发送到 PowerShell 主机进行显示,其实现取决于主机。控制台主机确实将它们发送到标准输出句柄(沿途通过Out-Default)。然而,PowerShell ISE 会在其输出窗格中显示它们,而其他主机可能会完全执行其他操作。 对象也不会盲目地转换为字符串,而是通过一个 formatter 来决定如何处理它们。这就是为什么您会看到 Get-ChildItem 的输出以表格形式出现,而具有许多属性(例如 WMI)的结果默认为 Format-List【参考方案2】:

我认为在这种情况下你需要Write-Output。

如果你有类似的脚本

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

然后,如果您调用带有重定向输出的脚本,例如yourscript.ps1 > out.txt,您将在“out.txt”中的屏幕test1\ntest3\n 上获得test2

请注意,“test3”和 Write-Output 行将始终在您的文本中追加一个新行,并且在 PowerShell 中无法停止(也就是说,echo -n 在带有本机命令的 PowerShell 中是不可能的)。如果您想要echo -n 的功能(Bash 中的一些基本和简单的功能),请参阅samthebest's answer。

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

【讨论】:

【参考方案3】:

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

【讨论】:

我可以看一整天...但是为什么$x = test 只打印123 而不是456 Write-Output(或 echo)将指定的对象写入管道。如果 Write-Output 是管道中的最后一个命令,则对象将显示在控制台中。这是倒数第二个,是否正在通过管道传递到 return 语句并添加数组 docs.microsoft.com/en-us/powershell/module/…【参考方案4】:

您可以在您的场景中使用其中任何一种,因为它们会写入默认流(输出和错误)。如果您要将输出通过管道传输到另一个命令行开关,您可能需要使用Write-Output,它最终将在Write-Host 中终止。

本文介绍了不同的输出选项:PowerShell O is for Output

【讨论】:

感谢您的链接。天哪,这复杂。如果 Write-host 是某种端点或刷新功能,我将尝试使用它并报告。【参考方案5】:

什么是写入 Windows 等效标准输出的正确方法?

效果,但非常不幸Windows PowerShell 和 PowerShell Core v7.2,发送 当通过 PowerShell 的 CLI从外部调用 时,所有 6(!) output streams 到 stdout强>。

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

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

例如,如果您从 cmd.exe 运行以下命令,您将看到 no 输出,因为到 NUL 的 stdout 重定向同样适用于所有 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,这是唯一的选择,因为between进程仅存在 2 个输出流 - data 的 stdout(标准输出)和错误消息的 stderr(标准错误)所有其他类型的消息- 例如状态信息 - 不是数据

建议在您的代码中做出这种区分,即使目前尚未得到尊重


内部 PowerShell

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

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

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

Write-Error 用于非终止错误写入错误流(编号@987654338 @);从概念上讲,错误流相当于标准错误。

Write-Output 写入成功[输出]流(编号1),在概念上相当于stdout;它是要写入数据(结果)的流。

但是,由于 PowerShell 的 隐式输出 功能,很少需要显式使用 Write-Output任何未明确捕获、抑制或重定向的命令或表达式的输出会自动发送到成功流;例如,Write-Output "Honey, I'm $HOME""Honey, I'm $HOME" 是等价的,后者不仅更简洁,而且速度更快。 请参阅this answer 了解更多信息。

【讨论】:

【参考方案6】:
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta

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

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

【讨论】:

【参考方案7】:

您根本无法让 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 中重定向它。 当然可以。见this question

以上是关于如何在 PowerShell 中输出内容的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Windows Power Shell

如何使用Windows Power Shell

win10下,cmd,power shell设置默认编码为‘UTF-8

win10用power shell安装appx文件怎么改安装路径

如何在Windows Server 2008 R2上开启Windows Power Shell ISE

powershell 更新power shell中的帮助系统。第二个文件在Windows中显示帮助文件。第三个文件显示来自在线来源的帮助。