【问题标题】:Is the first element of a powershell array always "true"?powershell 数组的第一个元素是否总是“真”?
【发布时间】:2014-12-27 03:39:18
【问题描述】:

arg1我有一些代码可以创建一个空的 powershell 数组,然后在 do..while 循环中将项目添加到这个数组中。出于某种原因,无论我做什么,数组中的第一个元素都是“真”。为什么是这样?

在我下面的代码中,您会注意到循环从外部 exe 一次添加一行输出。 exe 永远不会返回“true”,您可以看到我正在为每个添加到数组中的它执行 Write-Host,并且此 Write-Host 调用从来没有“true”输出。我的脚本中没有其他代码可以将任何元素添加到数组中。这令人沮丧,因为数组的索引搞砸了。这实质上使这个数组以 1 为索引而不是 0 为索引。有人对这里发生的事情有任何想法吗?

另外,还有一件事需要注意,在我初始化数组后,我将长度写入主机,它是 0,然后在我不添加所有项目之后,长度就是我期望的长度,如果“ true" 不是第一个元素。因此,如果外部应用程序返回 4 行,那么第二个 Write-Host $output.Length 调用将输出 4。

这是我的代码:

$output = @()
Write-Host "OUTPUT LENGTH START: $($output.Length)" -ForegroundColor Yellow
$continue = $true
do {
    $tempoutput = $Process.StandardOutput.ReadLine()
    if(($tempoutput -ne $null) -and ([string]::IsNullOrWhiteSpace($tempoutput) -ne $true)) {
        Write-Host $tempoutput -ForegroundColor DarkGray
        $output += $tempoutput
    } else {
        $continue = $false
    }
}
while($continue -eq $true)
Write-Host "OUTPUT LENGTH END: $($output.Length)" -ForegroundColor Yellow

另外,在我的函数结束时,我会像这样返回输出数组:

$output

然后在调用我的函数的代码中,如果我对返回的数组元素执行 foreach,“True”将始终是该数组中的第一项。

编辑以包含完整功能 这是我删除了所有 Write-Host 调用的完整功能:

function Execute-HttpManager($arguments, $filepath){
    $ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo 
    $ProcessInfo.FileName = $filepath 
    $ProcessInfo.RedirectStandardError = $true 
    $ProcessInfo.RedirectStandardOutput = $true 
    $ProcessInfo.RedirectStandardInput = $true
    $ProcessInfo.UseShellExecute = $false 
    $ProcessInfo.CreateNoWindow = $true
    $ProcessInfo.Arguments = $arguments
    $Process = New-Object System.Diagnostics.Process 
    $Process.StartInfo = $ProcessInfo

    $Process.Start() 
    $Process.WaitForExit() 

    $output = @()
    $continue = $true
    do {
        $tempoutput = $Process.StandardOutput.ReadLine()
        if(($tempoutput -ne $null) -and ([string]::IsNullOrWhiteSpace($tempoutput) -ne $true)) {
            $output += $tempoutput
        } else {
            $continue = $false
        }
    }
    while($continue -eq $true)

    $deployError = $Process.StandardError.ReadToEnd()

    $exitcode = $Process.ExitCode

    if($exitcode -eq 4) {
        $deployagainresponse = Read-Host
        if($deployagainresponse -eq 'y') {
            Deploy-Database $localapp $localsqlinstance $localdatabasename $localbackup $localsnapshot
        } elseif($deployagainresponse -ne 'bypass') {
            throw "http interaction failed with error.  Check the output."
        }
    } elseif ($exitcode -ne 0) {
        throw "Database deploy failed."
    }

    return $output
}

这是调用我的函数的代码:

$tokenoutput = Execute-HttpManager @("arg1", "arg2", "arg3", "arg4") $pathtoexecutable  

正是这个 $tokenoutput 变量在其数组的开头添加了“True”。

【问题讨论】:

  • 显示函数的完整定义和调用它的代码。凭直觉,尝试注释掉对Write-Host 的所有调用,看看您是否还有这个问题。
  • 没有看到整个功能,我们无法给您准确的回复。虽然您可能在最后输出 $Output,但该函数将传递任何具有输出的任何东西,而该输出并未在某个地方专门定向(例如 Write-Host 将事物定向到主机)。
  • 好的,我删除了所有的 write-host 调用,这并没有改变任何东西。我将完整的函数和调用它的代码添加到我的问题中。
  • 我打赌 $Process.Start() 输出 True。尝试将该行更改为[void]$Process.Start(),看看是否不能解决您的问题。
  • $Process.Start()$Process.WaitForExit() 以及对Deploy-Database 的调用可能会输出一些内容。要么在它前面加上[void],要么通过管道将它输出到空值(something | Out-Null)。

标签: powershell


【解决方案1】:

确保检查任何返回值的调用(例如 $Process.Start()),并在它们前面加上 [void] 或通过管道输出空值:$Process.Start() | Out-Null

任何功能都要注意这一点!函数输出的任何内容都是返回值的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多