openlang

-WhatIf 清理脚本说发现 13 个过期归档,可我一共只有 9 个文件

在我的 fedora 笔记本上清理旧的备份归档(pwsh 7.4,emacs,对,这已经快变成我给班上做的演示了)。脚本会在 ~/srv/archives 下找出比 KeepDays 更早的 *.tar.gz 并删掉,我会先带 -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. 固定链接

    插一句,既然这是要拿来做课堂演示的,用 “script” 这个词要小心。lib/Retention.ps1 里放的是一个函数,而 -WhatIf 之所以能用在你的主脚本上,只是因为它声明了 [CmdletBinding(SupportsShouldProcess)]。这不是什么魔法。学生常在这里搞混。顺便说,“我可不是野蛮人”这句放进幻灯片挺好。

    从英语翻译查看原文

同一个问题的其他角度

  1. httptest Server.Close 卡住,而且我的测试没有任何失败信息

    httptest.Server.Close 在 Go 1.23 上开启 keep-alive 时有可能卡住吗?我跑的是 go test -timeout 5s ./...,新写的测试既不通过也不失败。它一直挂到超时,然后我拿到 panic: test…

    回复 3最近活动 go
  2. 我的 init 只给一个 buffer 设置了 fill-column

    我的 init 里写了很久的 (setq fill-column 72),直到刚才才发现新建 buffer 里按 M-q 还是在 70 处折行。(在 *scratch* 里是在 72 处折行,我就是这样骗了自己。) fill-column 是自动 b…

    回复 3最近活动 emacs-lisp
  3. SilentlyContinue 就是拼写更好看的 On Error Resume Next

    从接手的工作簿换成接手的 PowerShell 脚本,结果在新外套里撞见了老朋友。一半的 cmdlet 调用上带着 -ErrorAction SilentlyContinue,其余的带着 2>$null(大概是以防万一吧)。 它比看上去更糟,是因为它…

    回复 0最近活动 powershell