在 while 循环中回显被添加到我的 return 值
echo in while loop get's added to my return value
我不确定如何在标题中描述这个问题,所以就这样吧。
我从另一个脚本中的脚本调用一个函数。在那个函数中,我有一个 while 循环,它基本上通过一组 ip 循环并查找它们的主机名。当 while 循环超时或我们拥有所有主机名时。
它 return 是主机名。
我的问题是 return 值包含我在该函数中所做的每一个 Write-Host。
我知道这是因为 Write-Host 将东西放在管道上,而 return 只是 return 它拥有的东西。
我该如何解决这个问题?
我 运行 得到的整个脚本记录在一个日志文件中,这就是为什么我想要一些详细的日志记录。
| write-host 上的 out-null 修复了该问题,但它不会在脚本中打印 write-host 值。
在 main.psm1 中我有一个像这样的函数:
$nodes = @("ip1", "ip2", "ip3", "ip4")
$nodesnames = DoStuff -nodes $nodes
然后在 functions.psm1 中我有如下函数:
Function DoStuff
{
param($nodes)
$timeout = 300
$timetaken = 0
$sleepseconds = 5
$nodenames = @("$env:COMPUTERNAME")
while(($nodenames.count -lt $nodes.count) -and ($timetaken -lt $timeout))
{
try
{
Write-Host "Stuff"
foreach($node in $nodes)
{
$nodename = SuperawesomeFunction $node
Write-Host "$nodename"
if($nodenames -notcontains $nodename)
{
$nodenames += @($nodename)
}
}
}
catch
{
Write-Host "DoStuff Failed because $_"
}
Start-Sleep $sleepseconds
$timetaken += $sleepseconds
}
return $nodenames
}
Function SuperawesomeFunction
{
param($node)
$nodename = [System.Net.Dns]::GetHostEntry("$node")
return $nodename
}
谢谢。
所以答案是,您的函数按照设计的方式工作。在 PowerShell 中,函数一般会 return 输出到管道,除非另有明确指示。
你之前使用了Echo
,它是Write-Output
的别名,并且输出如我之前提到的那样通过管道传递。因此,它将与 return
ed $nodenames
数组一起收集。
将 Echo
替换为 Write-Host
会改变一切,因为 Write-Host
明确告诉 PowerShell 将信息发送到主机应用程序(通常是 PowerShell 控制台或 PowerShell ISE)。
你如何避免这种情况?您可以添加一个参数来指定日志文件的路径,并让您的函数直接更新日志文件,并且仅输出相关数据。
或者您可以创建一个具有一对属性的对象,这些属性沿着管道传回,其中一个是 DNS 结果 属性,另一个是错误。
您可以在函数中使用 Write-Error,并将其设置为高级函数以支持 -errorvariable 并将错误捕获在单独的变量中。老实说,我不确定该怎么做,我从来没有做过,但我 90% 确定可以做到。
我不确定如何在标题中描述这个问题,所以就这样吧。 我从另一个脚本中的脚本调用一个函数。在那个函数中,我有一个 while 循环,它基本上通过一组 ip 循环并查找它们的主机名。当 while 循环超时或我们拥有所有主机名时。 它 return 是主机名。
我的问题是 return 值包含我在该函数中所做的每一个 Write-Host。
我知道这是因为 Write-Host 将东西放在管道上,而 return 只是 return 它拥有的东西。
我该如何解决这个问题? 我 运行 得到的整个脚本记录在一个日志文件中,这就是为什么我想要一些详细的日志记录。
| write-host 上的 out-null 修复了该问题,但它不会在脚本中打印 write-host 值。
在 main.psm1 中我有一个像这样的函数:
$nodes = @("ip1", "ip2", "ip3", "ip4")
$nodesnames = DoStuff -nodes $nodes
然后在 functions.psm1 中我有如下函数:
Function DoStuff
{
param($nodes)
$timeout = 300
$timetaken = 0
$sleepseconds = 5
$nodenames = @("$env:COMPUTERNAME")
while(($nodenames.count -lt $nodes.count) -and ($timetaken -lt $timeout))
{
try
{
Write-Host "Stuff"
foreach($node in $nodes)
{
$nodename = SuperawesomeFunction $node
Write-Host "$nodename"
if($nodenames -notcontains $nodename)
{
$nodenames += @($nodename)
}
}
}
catch
{
Write-Host "DoStuff Failed because $_"
}
Start-Sleep $sleepseconds
$timetaken += $sleepseconds
}
return $nodenames
}
Function SuperawesomeFunction
{
param($node)
$nodename = [System.Net.Dns]::GetHostEntry("$node")
return $nodename
}
谢谢。
所以答案是,您的函数按照设计的方式工作。在 PowerShell 中,函数一般会 return 输出到管道,除非另有明确指示。
你之前使用了Echo
,它是Write-Output
的别名,并且输出如我之前提到的那样通过管道传递。因此,它将与 return
ed $nodenames
数组一起收集。
将 Echo
替换为 Write-Host
会改变一切,因为 Write-Host
明确告诉 PowerShell 将信息发送到主机应用程序(通常是 PowerShell 控制台或 PowerShell ISE)。
你如何避免这种情况?您可以添加一个参数来指定日志文件的路径,并让您的函数直接更新日志文件,并且仅输出相关数据。
或者您可以创建一个具有一对属性的对象,这些属性沿着管道传回,其中一个是 DNS 结果 属性,另一个是错误。
您可以在函数中使用 Write-Error,并将其设置为高级函数以支持 -errorvariable 并将错误捕获在单独的变量中。老实说,我不确定该怎么做,我从来没有做过,但我 90% 确定可以做到。