繁体   English   中英

如何在 PowerShell 中输出内容

[英]How to output something in PowerShell

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

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

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

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

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

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

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

简单地输出一些东西是 PowerShell 是一件美丽的事情 - 也是它最大的优势。 例如,常见的 Hello, World! 应用程序减少到一行:

"Hello, World!"

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

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

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

如果你有一个像

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

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

请注意,“test3”和 Write-Output 行将始终在您的文本中附加一个新行,并且 PowerShell 无法阻止此操作(即,使用本机命令在 PowerShell 中无法使用echo -n )。 如果你想要(在Bash 中有点基本和简单)的echo -n功能,那么请参阅samthebest's answer

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

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

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

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

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

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

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

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

    • 例如,如果您从cmd.exe运行以下命令,您将看不到任何输出,因为重定向到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输出流存在-标准输出(标准输出)用于数据,和stderr(标准误差)的错误消息所有其它类型的消息-例如作为状态信息 - 这不是data

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


PowerShell 中

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

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

    • 由于现有不能被捕获或重定向,PowerShell的版本5由Write-Host写入到新引入的信息流(数6 ),因此从那时起,能够捕获和重定向Write-Host输出。

  • Write-Error用于非终止错误写入错误流(编号2 ); 从概念上讲,错误流相当于 stderr。

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

    • 但是,由于 PowerShell 的隐式输出功能,很少需要显式使用Write-Output
      • 任何未明确捕获、抑制或重定向的命令或表达式的输出都会自动发送到成功流 例如, Write-Output "Honey, I'm $HOME""Honey, I'm $HOME"是等价的,后者不仅更简洁,而且速度更快。
      • 有关更多信息,请参阅此答案
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是可选的,它显示了如何将变量放入字符串中。

您根本无法让 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脚本内部的外部程序:

cmd /c echo "Long string: $LongStr" 

在运行单独的进程方面,这是愚蠢且昂贵的,但PowerShell的设计很差。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM