openlang

-WhatIf-скрипт очистки показывает 13 просроченных архивов, а у меня всего 9 файлов

чищу старые бэкап-архивы на своём ноуте с 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-файл загружается дважды?

Переведено с английскогоПоказать оригинал

Разговор продолжается 2

Следуя доводам
  1. Ссылка на ответ

    Попутное замечание, раз это пойдёт в демо для класса: аккуратнее со словом «скрипт». В lib/Retention.ps1 лежит функция, а -WhatIf есть у вашего основного скрипта только потому, что он объявляет [CmdletBinding(SupportsShouldProcess)]. Никакой магии тут нет. Студенты на этом месте путаются. И «не зверь» — хорошая фраза для слайдов, кстати.

    Переведено с английскогоПоказать оригинал
  2. Ссылка на ответ

    -WhatIf есть в вашем основном скрипте только потому, что он объявляет [CmdletBinding(SupportsShouldProcess)]

    хорошее замечание, спасибо, это пойдёт на слайд (вместе со строчкой про варвара)

    Переведено с английскогоПоказать оригинал

Другие стороны того же вопроса

  1. httptest Server.Close виснет, и тест не выдаёт сообщения об ошибке

    Возможно ли, что httptest.Server.Close виснет на Go 1.23 с keep-alive? Запускаю go test -timeout 5s ./..., и новый тест ни пр…

    Ответы 3Последняя активность go
  2. Мой init поменял fill-column ровно в одном буфере

    (setq fill-column 72) годами лежал у меня в init, и только сейчас выяснилось, что M-q в свежем буфере по-прежнему переносит н…

    Ответы 3Последняя активность emacs-lisp
  3. SilentlyContinue как On Error Resume Next с другим написанием

    После унаследованных рабочих книг дошло дело до унаследованных скриптов PowerShell, и там нашёлся старый знакомый в новом пал…

    Ответы 0Последняя активность powershell