PowerShell:ForEach-Object循环内switch中$_的作用域问题
PowerShell中Switch语句内
$_无输出的问题解析 问题场景
尝试执行以下简化脚本时,ForEach-Object内的第一个Write-Host $_.Name能正常输出bat文件名,但switch语句内的Write-Host $_.Name无任何输出:
$i = 0 Get-ChildItem -Filter *.bat| ForEach-Object { Write-Host $_.Name switch ($i) { 0 { Write-Host $_.Name} 1 { Write-Host $_.Name } 2 { Write-Host $_.Name } Default {Write-Host "nothing here"} } }
但将文件名存入临时变量$temp后,switch内外都能正常输出:
$i = 0 Get-ChildItem -Filter *.bat | ForEach-Object { Write-Host $_.Name $temp = $_.Name switch ($i) { 0 { Write-Host $temp } 1 { Write-Host $temp } 2 { Write-Host $temp } Default {Write-Host "nothing here"} } }
核心原因
这是PowerShell自动变量$_的上下文动态绑定特性导致的:
- 在
ForEach-Object脚本块中,$_指向当前遍历的文件对象,因此能正常获取.Name属性 - 进入
switch ($i)语句后,switch会将$_重新绑定到当前匹配的目标值(即$i=0),此时$_是数字类型,没有.Name属性,自然无输出
你可以在switch脚本块内添加Write-Host $_验证,会发现输出的是数字0而非文件名。
解决方案
你使用临时变量的写法是最优解之一:
- 将文件对象的属性或整个对象存入独立变量(如
$temp = $_.Name或$currentFile = $_),避免switch对$_的覆盖影响 - 若要在switch中直接使用原始对象,也可以通过提前赋值的方式保留引用
内容的提问来源于stack exchange,提问作者robynChill
相关产品推荐
相关产品推荐

