首页 > 解决方案 > 如何通过管道将目录名称传递给 Set-Location cmdlet?

问题描述

我正在尝试查找某个命令的目录,然后将当前目录更改为找到的目录。

下面的命令给了我一个目录:

Get-Item -Path $(where.exe cmd.exe) | Select -Property Directory 

Directory
---------
C:\Windows\System32

现在我尝试将此目录通过管道传输到 Set-Location cmdlet,但收到错误消息:

Get-Item -Path $(where.exe cmd.exe) | Select -Property Directory | Set-Location

Set-Location : Cannot find drive. A drive with the name '@{Directory=C' does not exist.
At line:1 char:67
+ ... -Path $(where.exe cmd.exe) | Select -Property Directory |Set-Location
+                                                              ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{Directory=C:String) [Set-Location], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

我怎样才能做到这一点?请帮忙。

标签: powershell

解决方案


Get-Item -Path $(where.exe cmd.exe) | Select -ExpandProperty Directory | Set-Location

这个值得解释一下。

在文件系统中使用时,根据情况Get-Item返回一个FileInfoDirectoryInfo对象。他们都有Directory财产,到目前为止一切都很好。

Select-Object SomeProperty默认情况下,不会为您提供任何值SomeProperty。它为您提供了一个对象 (a PSObject),它SomeProperty是唯一的成员。这是为了支持你这样做的情况Select-Object SomeProperty, SomeOtherProperty

如果您想要输入对象的单个属性的原始值,则必须明确说明。就是Select-Object -ExpandProperty SomeProperty这样。(推论:你不能这样做Select-Object -ExpandProperty SomeProperty, SomeOtherProperty。)

Set-Location需要一个字符串。当您传递其他内容时,例如 a PSObject,它会将其转换为字符串。并且 a 的字符串表示形式PSObject不能用作路径,即使它是PSObject仅包含路径的 a。

另一种获取原始值的方法 - 直接属性访问 - 也可以(这可能是您从一开始就想到的):

(Get-Item -Path $(where.exe cmd.exe)).Directory | Set-Location    

并且由于我们已经确定Set-Location需要一个字符串,所以这也有效:

$(where.exe cmd.exe) | Split-Path -Parent | Set-Location

顺便说一句,有一种方便的方法可以用where.exePowerShell 原生的东西替换有点尴尬的调用 - Get-Command

Set-Location ((Get-Command cmd).Source | Split-Path -Parent)

推荐阅读