我正在编写一个自动评分脚本,当学生没有遵守目录要求时,它会向用户发出警告:具体来说,单身的文件,main.cpp
位于适当命名的文件夹中。如果在顶层找不到该文件,则警告用户,但继续在任何子目录中递归查找该文件。如果找不到文件,则发送错误,但继续处理父目录中的其余目录。
这是我迄今为止的尝试,但效果并不好——即使用户已经不 main.cpp
当我只想要 3 个可能的输出时,我根本不需要文件:
- 没有任何警告,继续建造;
- 递归找到文件,但发送了警告;
- 未找到文件且出错,但继续处理其他文件夹。
我该如何修复它?
function Copy-Files {
param (
[Parameter(Mandatory)][string]$CurrentDir,
[Parameter(Mandatory)][string]$StudentNum
)
# Try to copy assignment files to the marking folder. Check error conditions and warn marker appropriately.
try {
$DoneFiles | ForEach-Object {
Copy-Item -Force -Path "$CurrentDir\$_" -Destination .\marking -ErrorAction Stop
}
}
catch {
try {
$DoneFiles | ForEach-Object {
Get-ChildItem -Path $CurrentDir -File -Recurse -Filter "$_" | Copy-Item -Force -Destination .\marking -ErrorAction Stop
}
Write-Warning "$StudentNumber did not follow the specified folder convention, but all files were submitted."
}
catch {
Write-Error -Message "$StudentNumber did not submit any of: $DoneFiles." -Category InvalidData
Read-Host -Prompt "Press Enter to continue"
}
}
}
Get-ChildItem -Directory -Filter "*_lab${Env:AssignNumber}" | ForEach-Object {
$CurrentFolder = $_
$StudentNumber = $CurrentFolder.Name.Replace("_lab${Env:AssignNumber}", "")
Copy-Files -CurrentDir $CurrentFolder -StudentNum $StudentNumber
if ($AllFound -and $IsCMake) {
Invoke-CMake -DoneFileNames $DoneFiles -IsFirstCompile $FirstCompile -StudentNum $StudentNumber
}
# Run VS Code with diff
Compare-Code -DoneFileNames $DoneFiles -StudentNum $StudentNumber
}
答案1
问题在于 的一个尴尬行为Copy-Item
。如果您通过管道传递一个空/null 集合(例如来自Get-ChildItem
),它不会出错。与您可能预期的不同,因为管道确实$null
会引发错误:
Get-ChildItem './MySrc' -Filter 'BadFilter' | Copy-Item ./MyDst ## No Error
$Null | Copy-Item ./MyDst ## Does Error
If (Test-Path){}
对于文件,我更喜欢像Try
/这样的结构,Catch
以便在尝试更改之前确保路径等仍然有效:
# Check if file exists in correct path and copy,
If (Test-Path "$CurrentDir\$_") {
Copy-Item -Force -Path "$CurrentDir\$_" -Destination .\marking
}
# Otherwise check recursively for the correct file and show a warning if found
ElseIf (Get-ChildItem -Path $CurrentDir -File -Recurse -Filter "$_") {
Write-Warning "$StudentNumber did not follow the specified folder convention, but all files were submitted."
Get-ChildItem -Path $CurrentDir -File -Recurse -Filter "$_" |
Copy-Item -Force -Destination .\marking
}
# Error out if file not found
Else {
Write-Error -Message "$StudentNumber did not submit any of: $DoneFiles." -Category InvalidData
Read-Host -Prompt "Press Enter to continue"
}