为什么在.ps1与.psm1文件中$ _的行为有所不同?

alx*_*x9r 6 powershell pipeline module

假设你定义map_psmap.ps1:

function map_ps{
    [CmdletBinding()]
    param([parameter(ValueFromPipeline=$true)]$InputObject,$sb,$ArgumentList)
    process{&$sb $ArgumentList}
}
Run Code Online (Sandbox Code Playgroud)

假设您还在格式良好的模块中定义了另一个map_psm具有相同实现的函数,该模块称为:map.psm1

function map_psm{
    [CmdletBinding()]
    param([parameter(ValueFromPipeline=$true)]$InputObject,$sb,$ArgumentList)
    process{&$sb $ArgumentList}
}
Run Code Online (Sandbox Code Playgroud)

调用与每个功能相同的参数产生相同的结果:

PS C:\> 1 | map_ps  -sb {"DollarBar:$_, Arg:$($args[0])"} -ArgumentList 2
DollarBar:1, Arg:2
PS C:\> 1 | map_psm -sb {"DollarBar:$_, Arg:$($args[0])"} -ArgumentList 2
DollarBar:, Arg:2
Run Code Online (Sandbox Code Playgroud)

$_当函数在a中实现时为什么是空的.psm1但是当函数在a中实现时却不是.ps1

use*_*407 5

除非在全局范围内声明变量,否则functions/ScriptBlocks无法看到模块中声明的变量与其自己的模块不同.作为解决方法,您可以创建ScriptBlocks [scriptblock]::Create,从而创建不受任何特定模块约束的ScriptBlocks:

function FunctionWithoutModule{
    [CmdletBinding()]
    param([parameter(ValueFromPipeline=$true)]$InputObject,$sb,$ArgumentList)
    process{
        $SomeVariable='SomeValue'
        &$sb $ArgumentList
    }
}
$Module=New-Module -ScriptBlock {
    function FunctionWithModule{
        [CmdletBinding()]
        param([parameter(ValueFromPipeline=$true)]$InputObject,$sb,$ArgumentList)
        process{
            $SomeVariable='SomeValue'
            &$sb $ArgumentList
        }
    }
}
$ScriptBlockWithoutModule={"DollarBar:$_, Arg:$($args[0]), SomeVariable:$SomeVariable"}
$ScriptBlockWithModule=$Module.NewBoundScriptBlock($ScriptBlockWithoutModule)
$ScriptBlockNotBoundToModule=[scriptblock]::Create($ScriptBlockWithoutModule)

1|FunctionWithoutModule -sb $ScriptBlockWithoutModule -ArgumentList 2
#DollarBar:1, Arg:2, SomeVariable:SomeValue
1|FunctionWithoutModule -sb $ScriptBlockWithModule -ArgumentList 2
#DollarBar:, Arg:2, SomeVariable:
1|FunctionWithoutModule -sb $ScriptBlockNotBoundToModule -ArgumentList 2
#DollarBar:1, Arg:2, SomeVariable:SomeValue
1|FunctionWithModule -sb $ScriptBlockWithoutModule -ArgumentList 2
#DollarBar:, Arg:2, SomeVariable:
1|FunctionWithModule -sb $ScriptBlockWithModule -ArgumentList 2
#DollarBar:1, Arg:2, SomeVariable:SomeValue
1|FunctionWithModule -sb $ScriptBlockNotBoundToModule -ArgumentList 2
#DollarBar:1, Arg:2, SomeVariable:SomeValue
Run Code Online (Sandbox Code Playgroud)

  • 我从测试中发现这种行为.当带有模块概念的PowerShell V2到来时,我花了一些时间玩它,甚至找到一些[bug](https://connect.microsoft.com/PowerShell/feedback/details/569606).知识的某些部分来自于利用ILSpy挖掘.即使在回答这个问题时,我实际上发现没有模块的ScriptBlocks之间存在差异,并且ScriptBlocks没有限制到任何模块(通过`[scriptblock] :: Create`创建). (2认同)