开发者

Which lines are returning output in Powershell script?

In general, is there a convenient way to figure out which lines of a PowerShell script/function are returning values (are "uncaptured")? I was hoping there was a way to query the current state of the to-be-returned value whi开发者_C百科le debugging. I can check it after each line to see which lines add to it.

I have some scripts at work and some lines are turning my return value into an Object[]. I usually pipe such lines to Out-Null to fix the situation. I only want one object returned (the one I pick at the end of the function).

Some of the lines are Cmdlet calls, some are calls to other functions, and some are function calls on .NET objects.


I suppose you can use Set-PsDebug -trace 1 to see which line is returning them.

Example:

Consider the script below:

function f{
1..10
}

function g{
f
return 11
}

g

After doing Set-PsDebug -trace 1, the trace would be something like below:

DEBUG:    1+  <<<< .\test.ps1
DEBUG:    1+ function f <<<< {
DEBUG:    5+ function g <<<< {
DEBUG:   10+  <<<< g
DEBUG:    6+  <<<< f
DEBUG:    2+ 1.. <<<< 10
1
2
3
4
5
6
7
8
9
10
DEBUG:    7+ return <<<<  11
11

Clearly, you can see where the output is coming from. But if the output is captured, you wouldn't get this.

Also, if you don't care about the other objects that are being returned and only want to get the last one that you returned with the return statement, you can always do something like (func)[-1] or func | select -last 1 ( as pointed out in the comment) to get the last one.


To complete the possible answer, I'd like to add 2 notes:

First, if you use func | select -last 1, you have to wrap returned object to array, if you return array itself. Why? Look at a failing sample:

function MyOutputs {
    $list = new-Object Collections.ArrayList
    $list.Add('first')
    $list.Add('second')
    $list
}
myoutputs | Select -last 1 #doesn't work

Second, if you don't know exactly what commands return output, you can Out-Null them all like this:

function MyOutputs {
    . { 
        $list = new-Object Collections.ArrayList
        $list.Add('first')  # returns index
        $list.Add('second') # returns index
    } | Out-Null
    write-Host Returning...
    $list
}
$a = MyOutputs
Write-Host Result is
$a

Just try to put the ArrayList code outside the scriptblock and you will see what it does. Running it inside scriptblock with . notation means, that the scriptblock is executed in current scope. Out-Null just eats the output from Add methods.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜