提问人:Pekka 提问时间:1/11/2010 最后编辑:SquashmanPekka 更新时间:10/4/2021 访问量:745954
如何在 PowerShell 中输出内容
How to output something in PowerShell
问:
我正在批处理文件中运行 PowerShell 脚本。该脚本获取网页并检查该页面的内容是否为字符串“OK”。
PowerShell 脚本将错误级别返回到批处理脚本。
批处理脚本由 FTP 自动化程序 ScriptFTP 执行。如果发生错误,我可以让 ScriptFTP 通过电子邮件将完整的控制台输出发送给管理员。
在 PowerShell 脚本中,如果返回值不是“OK”,我想从网站输出返回值,因此错误消息将包含在控制台输出中,从而包含在状态邮件中。
我是 PowerShell 的新手,不确定要为此使用哪个输出函数。我可以看到三个:
- 写主机
- 写输出
- 写入错误
使用什么来写入 Windows 等效项是正确的?stdout
答:
您可以在方案中使用其中任何一个,因为它们写入默认流(输出和错误)。如果要将输出通过管道传递到另一个 commandlet,则需要使用 Write-Output,它最终将在 Write-Host 中终止。
本文介绍不同的输出选项: PowerShell O 用于输出
评论
我认为在这种情况下,您将需要 Write-Output。
如果你有一个像这样的脚本
Write-Output "test1";
Write-Host "test2";
"test3";
然后,如果您使用重定向输出调用脚本,例如 ,您将在“out.txt”中进入屏幕。yourscript.ps1 > out.txt
test2
test1\ntest3\n
请注意,“test3”和 Write-Output 行将始终在文本中附加一个新行,PowerShell 中没有办法阻止这种情况(也就是说,在 PowerShell 中使用本机命令是不可能的)。如果你想要(在 Bash 中有点基本和简单)功能,那么请看 samthebest 的答案。echo -n
echo -n
如果批处理文件运行 PowerShell 命令,则很可能会捕获 Write-Output 命令。我与系统管理员就哪些应该写入控制台以及哪些不应该写入进行了“长时间的讨论”。我们现在已经同意,脚本成功执行或死亡的唯一信息必须被“编辑”,并且脚本作者可能需要知道的有关执行的所有信息(更新了哪些项目,设置了哪些字段等)都转到了 Write-Output。这样,当您向系统管理员提交脚本时,他可以轻松地在屏幕上看到一切正常。然后将“someredirectedoutput.txt”发送回开发人员。Write-Host
runthescript.ps1 >someredirectedoutput.txt
简单地说,PowerShell 是一件美的事情,也是它最大的优势之一。例如,常见的 Hello, World!应用程序简化为一行:
"Hello, World!"
它创建一个字符串对象,分配上述值,并作为命令管道上的最后一项,它调用该方法并将结果输出到(默认情况下)。一件美丽的事情。.toString()
STDOUT
其他命令特定于将文本输出到其关联的流,并具有其位置。Write-*
评论
"Hello, World!" | Out-Host
Out-Host
Out-Default
Get-ChildItem
Format-List
你根本无法让 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
Magenta 可以是“System.ConsoleColor”枚举器值之一 - Black、DarkBlue、DarkGreen、DarkCyan、DarkRed、DarkMagenta、DarkYellow、Gray、DarkGray、Blue、Green、Cyan、Red、Magenta、Yellow、White。
是可选的,并显示如何将变量放入字符串中。+ $File.FullName
我认为以下是 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
使用什么来写入 Windows 等效的 stdout?
实际上,但非常不幸的是,从 v7.2 开始,Windows PowerShell 和 PowerShell Core 在通过 PowerShell 的 CLI 从外部调用时,都会将其所有 6(!) 输出流发送到 stdout。
请参阅 GitHub 问题 #7989 讨论此有问题的行为,该行为可能不会得到修复,以保持向后兼容性。
在实践中,这意味着将输出发送到的任何 PowerShell 流都将被视为外部调用方的 stdout 输出:
例如,如果从 运行以下命令,则不会看到任何输出,因为 stdout 重定向同样适用于所有 PowerShell 流:
cmd.exe
NUL
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
用于将非终止错误写入错误流(数字);从概念上讲,错误流等同于 stderr。2
Write-Output
写入成功 [output] 流 (number ),这在概念上等同于 stdout;它是要将数据(结果)写入的流。1
- 但是,由于 PowerShell 的隐式输出功能,很少需要显式使用
Write-Output
:- 任何未显式捕获、禁止或重定向的命令或表达式的输出都会自动发送到成功流;例如,和是等价的,后者不仅更简洁,而且更快。
Write-Output "Honey, I'm $HOME"
"Honey, I'm $HOME"
- 有关详细信息,请参阅此答案。
- 任何未显式捕获、禁止或重定向的命令或表达式的输出都会自动发送到成功流;例如,和是等价的,后者不仅更简洁,而且更快。
- 但是,由于 PowerShell 的隐式输出功能,很少需要显式使用
评论