11

我写了一个powershell脚本来比较两个文件夹的内容:

$Dir1 ="d:\TEMP\Dir1"
$Dir2 ="d:\TEMP\Dir2"

function Test-Diff($Dir1, $Dir2) {
    $fileList1 = Get-ChildItem $Dir1 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name
    $fileList2 = Get-ChildItem $Dir2 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name

    if($fileList1.Count -ne $fileList2.Count) {
        Write-Host "Following files are different:"
        Compare-Object -ReferenceObject $fileList1 -DifferenceObject $fileList2 -Property Name -PassThru | Format-Table FullName
        return $false
    }

    return $true
}

$i = Test-Diff $Dir1 $Dir2

if($i) { 
    Write-Output "Test OK" 
} else { 
    Write-Host "Test FAILED" -BackgroundColor Red
}

如果我在 上设置断点Compare-Object,并在控制台中运行此命令,我会得到差异列表。如果我运行整个脚本,我不会得到任何输出。为什么?

我正在使用 PowerGUI 脚本编辑器,但我也尝试了普通的 ps 控制台。

编辑:

问题是脚本末尾的检查。

$i = Test-Diff $Dir1 $Dir2

if($i) { 
   Write-Output "Test OK" 
...

如果我打电话Test-Diff$i =检查,它的工作原理!

Test-Diff返回一个对象数组,而不是预期的 bool 值:

[DBG]: PS D:\>> $i | ForEach-Object { $_.GetType() } | Format-Table -Property Name
 Name                                                                                                                        
 ----                                                                                                                        
 FormatStartData                                                                                                             
 GroupStartData                                                                                                              
 FormatEntryData                                                                                                             
 GroupEndData                                                                                                                
 FormatEndData                                                                                                               
 Boolean         

如果我用 注释掉该行Compare-Object,则返回值是一个布尔值,正如预期的那样。

问题是:为什么?

4

3 回答 3

12

我在这里找到了答案:http ://martinzugec.blogspot.hu/2008/08/returning-values-from-fuctions-in.html

像这样的函数:

Function bar {
 [System.Collections.ArrayList]$MyVariable = @()
 $MyVariable.Add("a")
 $MyVariable.Add("b")
 Return $MyVariable
}

使用 PowerShell 方式返回对象:@(0,1,"a","b") 而不是 @("a","b")

要使此函数按预期工作,您需要将输出重定向到 null:

Function bar {
 [System.Collections.ArrayList]$MyVariable = @()
 $MyVariable.Add("a") | Out-Null
 $MyVariable.Add("b") | Out-Null
 Return $MyVariable
}

在我们的例子中,函数必须按照 Koliat 的建议进行重构。

于 2014-03-27T09:06:06.787 回答
4

Out-Null在每个命令之后添加的替代方法,但最后一个是这样做:

$i = (Test-Diff $Dir1 $Dir2 | select -last 1)

PowerShell 函数始终将函数中执行的所有命令的结果作为 an 返回Object[](除非您将命令通过管道传输到Out-Null变量或将结果存储在变量中),但return语句后面的表达式始终是最后一个,并且可以使用select -last 1.

于 2019-10-18T14:38:40.120 回答
1

我已经修改了你的脚本,让它按照你想要的方式运行。我不确定您是否只想通过 .Count 属性比较文件,但它不在此问题的范围内。如果这不是您所关注的,请发表评论,我将尝试编辑此答案。基本上据我了解,您想在函数之后运行条件检查,而它可以在函数内部轻松实现。

$Dir1 ="C:\Dir1"
$Dir2 ="C:\Users\a.pawlak\Desktop\Dir2"

function Test-Diff($Dir1,$Dir2)
{
$fileList1 = Get-ChildItem $Dir1 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name
$fileList2 = Get-ChildItem $Dir2 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name

if ($fileList1.Count -ne $fileList2.Count)
{
Write-Host "Following files are different:"
Compare-Object -ReferenceObject $fileList1 -DifferenceObject $fileList2 -Property FullName -PassThru | Format-Table FullName
Write-Host "Test FAILED" -BackgroundColor Red

}
else 
{ 
return $true
Write-Output "Test OK" 
}
}

Test-Diff $Dir1 $Dir2

如果有什么不清楚的,请告诉我

亚历克斯

于 2014-03-26T15:33:27.890 回答