【发布时间】:2020-02-14 19:13:01
【问题描述】:
我编写这段代码是为了获取一些(相对)文件路径:
function Get-ExecutingScriptDirectory() {
return Split-Path $script:MyInvocation.MyCommand.Path # returns this script's directory
}
$some_file_path = Get-ExecutingScriptDirectory | Join-Path -Path $_ -ChildPath "foo.json"
这引发了错误:
Join-Path : Cannot bind argument to parameter 'Path' because it is null.
+ $some_file_path = Get-ExecutingScriptDirectory | Join-Path -Path $_ -ChildPath "fo ...
+ ~~
+ CategoryInfo : InvalidData: (:) [Join-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.JoinPathCommand
这向我表明Get-ExecutingScriptDirectory 的输出为空——但它不是——当我这样写脚本时,这很好:
$this_directory = Get-ExecutingScriptDirectory
$some_file_path = Join-Path -Path $this_directory -ChildPath "foo.json"
所以问题是$_ 为空。我希望$_ 引用前一个管道的标准输出。 MSDN documentation 也暗示了这一点,但它似乎立即自相矛盾:
$_ 包含管道对象中的当前对象。您可以在对每个对象或管道中的选定对象执行操作的命令中使用此变量。
在我的代码上下文中,$_ 似乎符合“管道对象中的当前对象”的条件 - 但我没有将它与对每个对象或管道中选定对象执行操作的命令一起使用.
$$ 和 $^ 看起来很有希望,但 MSDN 文档在这里只说了一些关于词法标记的模糊内容。 $PSItem 上的文档同样简洁。
我实际上喜欢做的是创建一个大管道:
$some_file_path = Get-ExecutingScriptDirectory | Join-Path -Path {{PREVIOUS STDOUT}} -ChildPath "foo.json" | Get-Content {{PREVIOUS STDOUT}} | Convert-FromJson {{PREVIOUS STDOUT}} | {{PREVIOUS STDOUT}}.data
我想知道我在概念和技术层面上哪里出错了。
【问题讨论】:
-
如果
Get-ExecutingScriptDirectory返回一个路径值,那么您可以将其直接通过管道传递到Join-Path,因为-Path参数通过管道接受值 -->Get-ExecutingScriptDirectory | Join-Path -ChildPath ...。您在此处没有当前输入对象$_,因为您没有使用带有可处理脚本块的命令。如果您使用Get-ExecutingScriptDirectory | Foreach-Object { },您将可以在Foreach脚本块中访问$_,并且可以根据自己的喜好创建其他变量。 -
@AdminOfThings
ForEach-Object在这里看起来很奇怪,因为前面的函数 (Get-ExecutingScriptDirectory) 只输出一个东西(一个字符串)。我不清楚它在技术上是否是“字符串类型的对象”。另外,我想将Get-ExecutingScriptDirectory的整个输出通过管道传递给Join-Path的一个参数,但我没有看到一个似乎合适的自动变量。 -
只需删除
-Path $_即可。 -
@AdminOfThings 是的,但是
Get-ExecutingScriptDirectory | Join-Path -ChildPath "foo.json" | Get-Content $_和Get-ExecutingScriptDirectory | Join-Path -ChildPath "foo.json" | Get-Content都无法工作。我不确定为什么前一个管道的标准输出会自动路由到-Path参数(与 -ChildPath 参数或其他参数相反)。 -
那是因为
Get-Content没有从管道中按值绑定的参数。您要么需要通过管道进入Foreach-Object并使用-Path $_,要么创建一个名为Path的对象属性,并将路径作为值,然后再通过管道传输到Get-Content。
标签: powershell visual-studio-code powershell-5.0