PowerShell mkdir别名+;设置StrictMode-版本2。奇怪的虫子。为什么?

PowerShell mkdir别名+;设置StrictMode-版本2。奇怪的虫子。为什么?,powershell,alias,mkdir,Powershell,Alias,Mkdir,真是难以置信。这是test.ps1文件中的PowerShell代码片段: Set-StrictMode -Version 2 mkdir c:\tmp\1 # same with 'md c:\tmp\1' 启动cmd.exe,使用test.ps1脚本导航到文件夹并运行它: c:\tmp>powershell ".\test.ps1" 这会产生以下错误: The variable '$_' cannot be retrieved because it has not been set

真是难以置信。这是
test.ps1
文件中的PowerShell代码片段:

Set-StrictMode -Version 2
mkdir c:\tmp\1  # same with 'md c:\tmp\1'
启动
cmd.exe
,使用
test.ps1
脚本导航到文件夹并运行它:

c:\tmp>powershell ".\test.ps1"
这会产生以下错误:

The variable '$_' cannot be retrieved because it has not been set.
At line:50 char:38
+         $steppablePipeline.Process($_ <<<< )
    + CategoryInfo          : InvalidOperation: (_:Token) [], ParentContainsEr
   rorRecordException
    + FullyQualifiedErrorId : VariableIsUndefined
无法检索变量“$\”,因为尚未设置该变量。
第50行字符:38

+$steppablePipeline.Process($\p>它看起来像是一个bug(在PowerShell中)。

即使已经找到了解决方法,我想人们可能会对解释感兴趣

至于为什么它在shell中的行为与cmd.exe不同,请参阅

如参考中所述,以下两个命令之间存在差异:

powershell ".\test.ps1"
powershell -File ".\test.ps1"
使用第一种语法时,它似乎会弄乱作用域,导致Set StrictMode命令修改在全局作用域中定义的函数的严格模式

这会在mkdir函数的定义中触发错误(或者错误的假设)

该函数使用GetSteppablePipeline方法为New-Item cmdlet代理管道。但是,作者忽略了一个事实,即即使管道中没有任何内容,流程节仍在执行。因此,当到达流程节时,未定义$自动变量。如果如果启用de,将发生异常

Microsoft解决此问题的一种方法是替换以下行:

    $steppablePipeline.Process($_)
以下是:

    if (test-path Variable:Local:_) {
        $steppablePipeline.Process($_)
    }
我承认这可能不是修复它的最佳方法,但开销可以忽略不计。另一种选择是以某种方式测试BEGIN部分中的管道是否为空,然后将$设置为$null


无论哪种方式,如果您使用“powershell.exe-File filename”语法运行脚本,那么您就不必担心它。

我使用了
新项目“blah”-类型目录作为解决方法。问题似乎只存在于
mkdir
md
别名。我将接受这个答案,但要注意“避免在您的PowerShell脚本中使用别名,您将不会遇到这种奇怪的问题”。但这与别名无关。
mkdir
是一个函数,在启用严格模式时会出现问题。