如何在 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;它是要写入数据(结果)的流。
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 中输出内容的主要内容,如果未能解决你的问题,请参考以下文章
win10下,cmd,power shell设置默认编码为‘UTF-8
win10用power shell安装appx文件怎么改安装路径
如何在Windows Server 2008 R2上开启Windows Power Shell ISE
powershell 更新power shell中的帮助系统。第二个文件在Windows中显示帮助文件。第三个文件显示来自在线来源的帮助。