Powershell退出循环导致无限递归

Powershell退出循环导致无限递归,powershell,for-loop,recursion,zip,infinite-loop,Powershell,For Loop,Recursion,Zip,Infinite Loop,出于某种原因,下面的powershell代码进入了一个无限循环,我不知道为什么 最低的try块中的代码无法成功,因此我希望catch捕获错误,然后循环继续 但是,它无限期地循环,创建越来越多的子目录 为什么呢 在powershell v5.0上测试 请在至少包含一个子文件夹的文件夹中尝试该代码,该文件夹本身至少包含一个文件。你会明白我的意思的 Get-ChildItem -Recurse | Where-Object { $_.PSIsContainer} | ForEach-Object {

出于某种原因,下面的powershell代码进入了一个无限循环,我不知道为什么

最低的
try
块中的代码无法成功,因此我希望
catch
捕获错误,然后循环继续

但是,它无限期地循环,创建越来越多的子目录

为什么呢

在powershell v5.0上测试

请在至少包含一个子文件夹的文件夹中尝试该代码,该文件夹本身至少包含一个文件。你会明白我的意思的

Get-ChildItem -Recurse | Where-Object { $_.PSIsContainer} | ForEach-Object {

    $path = $_
    set-Location $path

    #get all items, exclude zip files and folders
    $items = Get-ChildItem -Exclude *.zip | Where-Object { -not $_.psIsContainer}

    #verify that there are items in this directory, catch errors
    if ( $items ) {
        $newfld = New-Item -ItemType Directory -name "blabla"

        #move items to newly-created folder
        Move-Item $items -destination $newfld.Fullname 

        #try to do something that is destined to fail   
        try{
            [void][System.Reflection.Assembly]::LoadFrom($ZipModule)
        }
        catch { 
            Write-Host "No Zip"
        }
    }
}

您检查
$items
是否包含任何文件的方法过于复杂,其行为将与您预期的不同

您可以检查是否有任何文件仅返回了以下内容:

if($items){
    # move/zip/create etc.
}
如果
Get ChildItem
返回0个文件,
$items
将被解释为
$false
,否则
$true


关于无限循环行为,
getchilditem-Recurse
似乎在后台异步运行,并同时拾取您创建的
blablabla
文件夹

通过在
()
中包含调用,可以强制
Get ChildItem-Recurse
在管道传输到
ForEach对象之前返回:

或者,将所有目录(实际上只需要
FullName
属性)分配给循环前单独语句中的变量:

$Directories = Get-ChildItem -Recurse |Where-Object { $_.PsIsContainer } |Select-Object FullName
foreach($Path in $Directories){
    # create/move/zip etc.
}

您检查
$items
是否包含任何文件的方法过于复杂,其行为将与您预期的不同

您可以检查是否有任何文件仅返回了以下内容:

if($items){
    # move/zip/create etc.
}
如果
Get ChildItem
返回0个文件,
$items
将被解释为
$false
,否则
$true


关于无限循环行为,
getchilditem-Recurse
似乎在后台异步运行,并同时拾取您创建的
blablabla
文件夹

通过在
()
中包含调用,可以强制
Get ChildItem-Recurse
在管道传输到
ForEach对象之前返回:

或者,将所有目录(实际上只需要
FullName
属性)分配给循环前单独语句中的变量:

$Directories = Get-ChildItem -Recurse |Where-Object { $_.PsIsContainer } |Select-Object FullName
foreach($Path in $Directories){
    # create/move/zip etc.
}

它进入无限循环的原因是因为你要进入一个子文件夹,检查它是否有文件(非ZIP文件),如果有,创建一个名为“blabla”的新文件夹,并将文件移动到该文件夹中。因此,代码所做的就是将文件夹中的文件不断移动到该文件夹的子文件夹中,以此类推。如果您想将文件移动到子文件夹中,然后将其压缩并删除文件,那么将停止无限递归


每次创建子文件夹“blabla”时,您都会使递归永久化。

它进入无限循环的原因是因为您要进入子文件夹,请检查它是否有文件(非ZIP文件),如果有,请创建一个名为“blabla”的新文件夹,并将文件移动到该文件夹中。因此,代码所做的就是将文件夹中的文件不断移动到该文件夹的子文件夹中,以此类推。如果您想将文件移动到子文件夹中,然后将其压缩并删除文件,那么将停止无限递归


每次创建子文件夹“blabla”时,您都在使递归永久化。

if
语句中的
try{}catch{}
是怎么回事?字符串
“No items”
将被解释为
$true
,与
测试路径的目的不符。您的意思是什么?语句中的第一个
try{}catch{}
是检查文件夹是否包含项目,即
$items
不是空的。你不需要
测试路径
,只需检查
$items
是否包含任何内容:
如果($items){dostuff}
@mathiar.Jessen-这是非常有用的反馈,谢谢!不过,这根本不能回答我的问题。测试代码,你会明白我的意思。在
if
语句中的
try{}catch{}
是怎么回事?字符串
“No items”
将被解释为
$true
,与
测试路径的目的不符。您的意思是什么?语句中的第一个
try{}catch{}
是检查文件夹是否包含项目,即
$items
不是空的。你不需要
测试路径
,只需检查
$items
是否包含任何内容:
如果($items){dostuff}
@mathiar.Jessen-这是非常有用的反馈,谢谢!不过,这根本不能回答我的问题。测试代码,你会明白我的意思。好的,非常感谢。我已经做了更改,但是代码仍然是无限循环的。请在至少包含一个其他文件夹的文件夹中尝试,该文件夹本身至少包含一个文件。你会明白我的意思。没有注意到外部的
Get ChildItem-Recurse
调用,让我看看是否可以重新编程。啊,好吧,很公平。是的,代码设计用于压缩所有子文件夹的内容。然而,我注意到,如果压缩失败,那么循环将重新启动,并无限循环。顺便说一下,非常感谢您的帮助。@Charon-yup也可以在PowerShell 4.0中复制(和缓解)。见更新我见。。。。。谢谢这很有趣,你的答案很有效,所以我接受了。你有这方面的链接吗?好的,非常感谢。我已经做了更改,但是代码仍然是无限循环的。请在至少包含一个其他文件夹的文件夹中尝试,该文件夹本身至少包含一个文件。你会明白我的意思。没有注意到外部的
Get ChildItem-Recurse
调用,让我看看是否可以重新编程。啊,好吧,很公平。是的,代码设计用于压缩所有子文件夹的内容。然而,我注意到,如果压缩失败,那么循环将重新启动,并在无限的时间内循环