您可以将 Tee-Object 重定向到标准输出吗?
Can you redirect Tee-Object to standard out?
我正在编写脚本,我想传递这些值,但也想看到它们显示出来
Get-Content data.txt | Tee-Object | data_processor.exe
但是Tee-Object
总是请求一个文件,而我只想在屏幕上看到它。
您可以输出到变量而不是文件:
Get-Content data.txt | Tee-Object -Variable data | data_processor.exe
$data # Output
这会将内容传递给“data_processor.exe”并将其存储在变量$data
中。只有在 .exe 完成后才会显示数据。
在将每一行发送到 .exe 之前,使用 ForEach-Object
检查 Get-Content
的输出:
Get-Content data.txt | ForEach-Object {
Write-Host $_ # Output line to console
$_ # Forward line to next command in chain
} | data_processor.exe
可以通过编写一个小 filter function:
使此模式更加简洁和可重用
Filter Write-HostAndForward {
Write-Host $_ # Output line to console
$_ # Forward line to next command in chain
}
现在我们可以写:
Get-Content data.txt | Write-HostAndForward | data_processor.exe
备注:
虽然 Write-HostAndForward
适用于简单的输入,例如从 Get-Content
接收的字符串,但对于复杂的对象,它通常不会产生与我们通常在控制台中看到的相同的输出。这是因为 Write-Host
只是使用 .ToString()
方法将输入转换为字符串,这会跳过 PowerShell 的富格式系统。
您可能想简单地用 Out-Host
替换 Write-Host
,但是 mklement0 explains, it would format the input objects individually, which will produce a header for each object for table-formatted output. To avoid that, 显示了生成预期格式化输出的不同方法。
补充:
如果你是运行PowerShell (Core) 7+,你可以传递代表终端的文件路径(控制台) 到(位置隐含的)-FilePath
参数(在 Windows PowerShell 中,不幸的是,这会导致错误- 见底部):
# PowerShell 7+ only
# Windows
Get-Content data.txt | Tee-Object CON | data_processor.exe
# Unix-like platforms (Linux, macOS)
Get-Content data.txt | Tee-Object /dev/tty | data_processor.exe
# Platform-agnostic
Get-Content data.txt | Tee-Object ($IsWindows ? 'CON': '/dev/tty') | data_processor.exe
这 传递所有数据,同时还将其打印到终端(控制台),格式丰富,像往常一样,可用时 - 与 Tee-Object -Variable
方法不同,后者需要首先在内存中收集所有输出(这在输出时间和内存消耗方面都是一个问题)。
Windows PowerShell 解决方案:自定义 Tee-Host
wraps Out-Host
同时也传递其输入;使用它 代替 of Tee-Object
:
function Tee-Host {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)] $InputObject
)
begin
{
$scriptCmd = { Out-Host }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
}
process
{
# Pass to Out-Host, and therefore to the host (terminal)
$steppablePipeline.Process($InputObject)
# Pass through (to the success stream)
$InputObject
}
end
{
$steppablePipeline.End()
}
}
实际上,Tee-Host
的行为类似于 PowerShell 7+ 中的 Tee-Object CON
/ Tee-Object /dev/tty
,其中 Tee-Host
也有效。
即使在 PowerShell 7+ 中,Tee-Host
可能更可取,因为它使用 colored 输出 unconditionally ,而 Tee-Object CON
/ Tee-Object /dev/tty
的着色行为取决于 $PSStyle.OutputRendering
的值
使用代理函数和可步进管道包装 Out-Host
确保 to-host 格式化输出看起来与输入直接发送到主机时相同。
我正在编写脚本,我想传递这些值,但也想看到它们显示出来
Get-Content data.txt | Tee-Object | data_processor.exe
但是Tee-Object
总是请求一个文件,而我只想在屏幕上看到它。
您可以输出到变量而不是文件:
Get-Content data.txt | Tee-Object -Variable data | data_processor.exe
$data # Output
这会将内容传递给“data_processor.exe”并将其存储在变量$data
中。只有在 .exe 完成后才会显示数据。
在将每一行发送到 .exe 之前,使用 ForEach-Object
检查 Get-Content
的输出:
Get-Content data.txt | ForEach-Object {
Write-Host $_ # Output line to console
$_ # Forward line to next command in chain
} | data_processor.exe
可以通过编写一个小 filter function:
使此模式更加简洁和可重用Filter Write-HostAndForward {
Write-Host $_ # Output line to console
$_ # Forward line to next command in chain
}
现在我们可以写:
Get-Content data.txt | Write-HostAndForward | data_processor.exe
备注:
虽然 Write-HostAndForward
适用于简单的输入,例如从 Get-Content
接收的字符串,但对于复杂的对象,它通常不会产生与我们通常在控制台中看到的相同的输出。这是因为 Write-Host
只是使用 .ToString()
方法将输入转换为字符串,这会跳过 PowerShell 的富格式系统。
您可能想简单地用 Out-Host
替换 Write-Host
,但是 mklement0 explains, it would format the input objects individually, which will produce a header for each object for table-formatted output. To avoid that,
补充
如果你是运行PowerShell (Core) 7+,你可以传递代表终端的文件路径(控制台) 到(位置隐含的)-FilePath
参数(在 Windows PowerShell 中,不幸的是,这会导致错误- 见底部):
# PowerShell 7+ only
# Windows
Get-Content data.txt | Tee-Object CON | data_processor.exe
# Unix-like platforms (Linux, macOS)
Get-Content data.txt | Tee-Object /dev/tty | data_processor.exe
# Platform-agnostic
Get-Content data.txt | Tee-Object ($IsWindows ? 'CON': '/dev/tty') | data_processor.exe
这 传递所有数据,同时还将其打印到终端(控制台),格式丰富,像往常一样,可用时 - 与 Tee-Object -Variable
方法不同,后者需要首先在内存中收集所有输出(这在输出时间和内存消耗方面都是一个问题)。
Windows PowerShell 解决方案:自定义 Tee-Host
wraps Out-Host
同时也传递其输入;使用它 代替 of Tee-Object
:
function Tee-Host {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)] $InputObject
)
begin
{
$scriptCmd = { Out-Host }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
}
process
{
# Pass to Out-Host, and therefore to the host (terminal)
$steppablePipeline.Process($InputObject)
# Pass through (to the success stream)
$InputObject
}
end
{
$steppablePipeline.End()
}
}
实际上,
Tee-Host
的行为类似于 PowerShell 7+ 中的Tee-Object CON
/Tee-Object /dev/tty
,其中Tee-Host
也有效。即使在 PowerShell 7+ 中,
的值Tee-Host
可能更可取,因为它使用 colored 输出 unconditionally ,而Tee-Object CON
/Tee-Object /dev/tty
的着色行为取决于$PSStyle.OutputRendering
使用代理函数和可步进管道包装 Out-Host
确保 to-host 格式化输出看起来与输入直接发送到主机时相同。