我可以确定 PowerShell 函数是否作为管道的一部分运行吗?
PowerShell 函数能否确定它是否作为管道的一部分运行?我有一个函数,它用 FileInfo
的实例填充一个数组,如果该函数以这种方式运行,我希望“屈服”到管道,或者如果该函数被调用,则产生一些漂亮的输出本身来自命令行。
function Do-Something {
$file_infos = @()
# Populate $file_infos with FileInfo instances...
if (INVOKED_IN_PIPELINE) {
return $file_infos
}
else {
foreach ($file_info in $file_infos) {
write-host -foregroundcolor yellow $file_info.fullname
}
}
}
基本上,我试图弄清楚如何实现INVOKED_IN_PIPELINE
。如果它在管道中运行(例如Do-Something | format-table fullname
),我会简单地生成数组,但如果直接运行(例如Do-Something
) ,它会将数组的内容漂亮地打印到控制台。
有办法做到这一点吗?如果有更“惯用”的方式来实现这种事情,我也有兴趣知道。
Can a PowerShell function determine if it is being run as part of a pipeline? I have a function which populates an array with instances of FileInfo
which I would like to "yield" to the pipeline if the function is being run this way or produce some pretty output if the function is being invoked by itself from the command line.
function Do-Something {
$file_infos = @()
# Populate $file_infos with FileInfo instances...
if (INVOKED_IN_PIPELINE) {
return $file_infos
}
else {
foreach ($file_info in $file_infos) {
write-host -foregroundcolor yellow $file_info.fullname
}
}
}
Basically, I'm trying to figure out how to implement INVOKED_IN_PIPELINE
. If it is run in a pipeline (e.g. Do-Something | format-table fullname
), I would simply yield the array, but if run directly (e.g. Do-Something
), it would pretty-print the contents of the array to the console.
Is there a way to do this? If there is a more "idiomatic" way to achieve this kind of thing, I would also be interested to know.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此信息作为 $PSCmdlet.MyInspiration 的一部分提供。您可以使用以下 cmdlet 来进行实验。它的作用是为任何命令执行一次写出该属性的内容,然后传递对象(以便您可以使用更大的管道更多地操作对象)。您将看到有一个名为
PipelineLength
的属性,当您单独运行此命令时,该属性等于 1,并且对于管道中的每个项目都会增加。另请注意PipelinePosition
。它告诉您这个命令在管道中的位置。注意:
$PSCmdlet
仅在您编写高级函数时可用(例如具有[CmdletBinding()]
属性。以下是一些示例:
This information is available as part of $PSCmdlet.MyInvocation. Here is a cmdlet you can use to experiment with this. What it does it to write out the contents of that property once for any command execution and then passes on the object (so you can manipulate the objects some more with bigger pipelines). What you'll see is that there is a property called
PipelineLength
which is equal to 1 when you run this command by itself and increases for each item in the pipeline. Also noticePipelinePosition
. It tells you what position this command is in the pipeline.NOTE:
$PSCmdlet
is only available when you write an advanced function (e.g. have the[CmdletBinding()]
attribute.Here are some examples:
执行此操作的“惯用”方法是输出特定的对象类型,然后为该对象定义格式化数据。该对象可以是自定义(基于 C#/VB 的对象)或命名的 PSObject。这种方法的优点是您可以只输出这些对象,如果没有进一步的管道输出格式(即使用
Format
命令),那么将使用您定义的默认输出格式。否则,Format
命令之一可以覆盖该默认格式。下面是一个示例:请注意,我们第二次将
$obj
发送到管道中时,默认输出有何不同。这是因为它使用了提供的自定义格式指令,因为没有使用显式格式命令。顺便说一句,即使对于
$obj
也总是有一个管道,因为它隐式地通过管道传输到Out-Default
。以下是在我命名为 MyCustomFormatData.xml 的
.ps1xml
文件中定义的自定义格式定义:有关如何格式化自定义对象的更多示例,请查看此命令输出的文件:
The "idiomatic" way to do this is to output a specific object type and then define formatting data for that object. The object can be a custom (C#/VB-based object) or a named PSObject. The advantage of this approach is that you can just output these objects and if there is no further pipeline output formatting (ie use of a
Format
command) then you're defined default output formatting will get used. Otherwise, one of theFormat
commands can override that default formatting. Here's an example:Notice how the default output is different the second time we sent
$obj
down the pipe. That's because it used the custom formatting instructions provided since there were no explicit formatting commands used.BTW there is always a pipeline even for
$obj
because that is implicitly piped toOut-Default
.Here is the custom format definition that is defined in a
.ps1xml
file that I named MyCustomFormatData.xml:For more examples of how to format custom objects look at the files output by this command: