чищу старые бэкап-архивы на своём ноуте с fedora (pwsh 7.4, emacs, и да, это превращается в демо для моего класса). скрипт находит *.tar.gz старше KeepDays в ~/srv/archives и удаляет их, а я сначала запускаю с -WhatIf, потому что я не зверь.
в папке 9 архивов в 3 подпапках. руками насчитал 4 старше 30 дней. в логе found 13 expired archives. потом foreach выводит несколько нормальных строк What if: Performing the operation "Remove archive" on target ..., но между ними падает с The property 'FullName' cannot be found on this object. Verify that the property exists. на строке $item.FullName.
решил, что strict mode придирается к FileInfo, и закомментировал Set-StrictMode -Version Latest. ошибки пропали, счётчик всё равно 13. Get-ChildItem ... | Measure-Object вручную даёт 9, это правильно. так откуда лишние 9 «элементов» и почему падают только некоторые? (транскрипт сейчас приложить не могу, это по памяти с терминала.)
функция в lib/Retention.ps1:
$cutoff = (Get-Date).AddDays(-$KeepDays)
$seenDirs = [System.Collections.Generic.HashSet[string]]::new()
$expired = [System.Collections.Generic.List[System.IO.FileInfo]]::new()
foreach ($f in Get-ChildItem -Path ... -Recurse -File -Filter '*.tar.gz') {
$seenDirs.Add($f.DirectoryName)
if ($f.LastWriteTime -lt $cutoff) {
$expired.Add($f)
}
}
Write-Verbose "scanned $($seenDirs.Count) directories"
return $expired
а в основном скрипте:
$expired = Find-ExpiredArchives -Root $root -KeepDays $KeepDays
Write-LogLine "found $($expired.Count) expired archives"
foreach ($item in $expired) {
if ($PSCmdlet.ShouldProcess($item.FullName, 'Remove archive')) {
Remove-Item -LiteralPath $item.FullName
$freed += $item.Length
}
}
-Recurse вместе с -Filter делает что-то странное, или lib-файл загружается дважды?