fedora 노트북에서 오래된 백업 아카이브를 정리하고 있어요 (pwsh 7.4, emacs, 그리고 네, 이거 수업 데모가 되어가고 있어요). 스크립트는 ~/srv/archives 아래에서 KeepDays보다 오래된 *.tar.gz를 찾아서 지우는데, 저는 짐승이 아니라서 먼저 -WhatIf로 돌려봐요.
폴더에는 서브폴더 3개에 걸쳐 아카이브가 9개 있어요. 직접 세어보면 30일보다 오래된 건 4개예요. 그런데 로그에는 found 13 expired archives라고 나와요. 그다음 foreach가 What if: Performing the operation "Remove archive" on target ... 줄을 제대로 몇 개 출력하다가, 중간에 $item.FullName 줄에서 The property 'FullName' cannot be found on this object. Verify that the property exists. 하고 죽어요.
strict mode가 FileInfo에 대해 까다롭게 구는 건가 싶어서 Set-StrictMode -Version Latest를 주석 처리했어요. 에러는 사라졌는데 개수는 여전히 13이에요. 직접 Get-ChildItem ... | Measure-Object를 해보면 9가 나오고, 이건 맞아요. 그럼 늘어난 9개의 "아이템"은 어디서 나오는 건지, 그리고 왜 일부만 터지는 건지 모르겠어요. (지금은 transcript를 붙여넣을 수 없어서, 터미널에서 본 걸 기억으로 적었어요.)
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 파일이 두 번 로드되는 건가요?
영어에서 번역·원문 보기tidying old backup archives on my fedora laptop (pwsh 7.4, emacs, and yes this is becoming a demo for my class). the script finds *.tar.gz older than KeepDays under ~/srv/archives and removes them, and i run it with -WhatIf first because i'm not an animal.
the folder has 9 archives across 3 subfolders. by hand i count 4 older than 30 days. the log says found 13 expired archives. then the foreach prints a few proper What if: Performing the operation "Remove archive" on target ... lines, but in between it dies with The property 'FullName' cannot be found on this object. Verify that the property exists. on the $item.FullName line.
i figured strict mode was being fussy about FileInfo, so i commented out Set-StrictMode -Version Latest. errors gone, count still 13. Get-ChildItem ... | Measure-Object by hand gives 9, which is right. so where do the extra 9 "items" come from, and why do only some blow up? (i can't paste a transcript right now, this is from memory of the terminal.)
the function in 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
and in the main script:
$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
}
}
is -Recurse with -Filter doing something weird, or is the lib file getting loaded twice?