在PowerShell中相当于* Nix'哪个'命令?


Answers:


390

在PowerShell中开始自定义配置文件后,我创建的第一个别名是“哪个”。

New-Alias which get-command

要将其添加到您的个人资料,请键入:

"`nNew-Alias which get-command" | add-content $profile

最后一行的开始处的`n是为了确保它将以新行开始。


1
您可以将其放在配置文件脚本中。有关配置文件的更多信息-msdn.microsoft.com/zh-cn/library/bb613488(VS.85).aspx
Steven Murawski

61
我喜欢跑步:Get-Command <command> | Format-Table Path, Name这样我也可以获得命令所在的路径。
jrsconfitto 2012年

4
有没有办法一直保持路径而无需键入'| 格式表路径,名称'?
纪尧姆

10
如果要使用Unix风格的行为给您路径,则需要将get-command的输出传递给select -expandproperty Path
Casey 2015年

5
用于(gcm <command>).definition仅获取路径。gcm是的默认别名Get-Command。您也可以使用通配符,例如:(gcm win*.exe).definition
萨钦·约瑟夫

165

这是一个等效的* nix实际值,即给出* nix样式的输出。

Get-Command <your command> | Select-Object -ExpandProperty Definition

只需替换为您要的内容。

PS C:\> Get-Command notepad.exe | Select-Object -ExpandProperty Definition
C:\Windows\system32\notepad.exe

将其添加到配置文件时,您将要使用函数而不是别名,因为您不能在管道中使用别名:

function which($name)
{
    Get-Command $name | Select-Object -ExpandProperty Definition
}

现在,当您重新加载个人资料时,您可以执行以下操作:

PS C:\> which notepad
C:\Windows\system32\notepad.exe

22
我使用这种备用语法:“((Get-Command notepad).definition”
Yann

2
@ B00merang您的语法很棒-绝对更加简洁-但不幸的是,即使删除了管道,也不能将其作为别名添加,除非您包含要查找的程序的名称。
petrsnd 2014年

4
这是一篇旧文章,但是如果有人将Google发送到这里(就像我以前一样),那么该答案可以使用比接受的答案更多类型的Powershell命令。例如,我有一个别名okta,该别名指向okta.ps1不在我的Powershell脚本上$PATH。使用接受的答案将返回脚本名称(okta -> okta.ps1)。可以,但不会告诉我的位置okta.ps1。但是,使用此答案可以给我完整的路径(C:\Users\blah\etc\scripts\okta.ps1)。所以我+1。
斯凯岛队长

87

我通常只输入:

gcm notepad

要么

gcm note*

gcm是Get-Command的默认别名。

在我的系统上,gcm note *输出:

[27] » gcm note*

CommandType     Name                                                     Definition
-----------     ----                                                     ----------
Application     notepad.exe                                              C:\WINDOWS\notepad.exe
Application     notepad.exe                                              C:\WINDOWS\system32\notepad.exe
Application     Notepad2.exe                                             C:\Utils\Notepad2.exe
Application     Notepad2.ini                                             C:\Utils\Notepad2.ini

您将得到与您要查找的目录和命令匹配的目录。


它有点乱,但路除渣比自定义功能和任意拆分
DevelopingChris

1
当我在powershell命令提示符下键入“ gcm notepad”时,我仅获得前两列,以及名为“ ModuleName”的第三列,该列为空。您是否知道如何强制其默认列出“定义”列?
Piyush Soni

3
@PiyushSoni可能是因为PowerShell的更新版本。您总是可以通过执行类似操作来显示其他列gcm note* | select CommandType, Name, Definition。如果您经常运行它,则可能应该将其包装在一个函数中。
David Mohundro '16

40

试试这个例子:

(Get-Command notepad.exe).Path

2
请添加更多代码或说明,以便OP可以更好地了解您。谢谢。
sshashank124 2014年

3
感谢您添加的代码更少,因此我实际上可以一次记住它:P
albertjan

1
这就是我想要的!它也适用于gcm:(gcm py.exe).path
Bill Agee

7

我对Who函数的主张:

function which($cmd) { get-command $cmd | % { $_.Path } }

PS C:\> which devcon

C:\local\code\bin\devcon.exe

这是一个比公认的更好的答案。它允许您添加上面建议的后处理后缀,以提供更好的输出。别名没有。
BobHy

5

与Unix的快速混搭which

New-Alias which where.exe

但是它返回多行(如果存在的话),那么它变成

function which {where.exe command | select -first 1}

1
where.exe where应该告诉你C:\Windows\System32\where.exe
Chris F Carroll

1
where.exe等价于which -a,因为它会返回所有匹配的可执行文件,而不仅仅是第一个要执行的可执行文件。即,where.exe notepad给出c:\windows\notepad.exec:\windows\system32\notepad.exe。因此,这特别适合该形式$(which command)。(另一个问题是,如果未找到该命令,它将打印出一条非常有用的错误消息,该命令也不会很好地扩展$()-可以用来补救/Q,但不能作为别名。)
Jeroen Mostert

点。我编辑了答案,但是是的,它不再是那么整洁的解决方案了
克里斯·卡罗尔

1
请注意,where似乎搜索的是系统PATH变量,而不是当前的shell PATH变量。看到这个问题
Leonardo

3

这似乎可以满足您的要求(我在http://huddledmasses.org/powershell-find-path/上找到了它):

Function Find-Path($Path, [switch]$All = $false, [Microsoft.PowerShell.Commands.TestPathType]$type = "Any")
## You could comment out the function stuff and use it as a script instead, with this line:
#param($Path, [switch]$All = $false, [Microsoft.PowerShell.Commands.TestPathType]$type = "Any")
   if($(Test-Path $Path -Type $type)) {
      return $path
   } else {
      [string[]]$paths = @($pwd);
      $paths += "$pwd;$env:path".split(";")

      $paths = Join-Path $paths $(Split-Path $Path -leaf) | ? { Test-Path $_ -Type $type }
      if($paths.Length -gt 0) {
         if($All) {
            return $paths;
         } else {
            return $paths[0]
         }
      }
   }
   throw "Couldn't find a matching path of type $type"
}
Set-Alias find Find-Path

但这并不是真正的“哪个”,因为它可以与任何文件(类型)一起使用并且找不到cmdlet,函数或别名
Jaykul 2014年

3

检查此PowerShell其中

此处提供的代码表明:

($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe

2
我知道它已经很多年了,但是我的路径中包含“%systemroot%\ system32 \ ...”,PowerShell不会扩展该环境变量,并且这样做会引发错误。
TessellatingHeckler 2014年

3

我喜欢Get-Command | Format-List,或更短地说,对两个都使用别名,并且仅对powershell.exe

gcm powershell | fl

您可以找到这样的别名:

alias -definition Format-List

制表符补全适用于gcm


2

where在Windows 2003或更高版本(或Windows 2000 / XP,如果已安装资源工具包)上尝试命令。

顺便说一句,这在其他问题上获得了更多答案:

Windows上有与“哪个”等效的东西吗?

PowerShell相当于Unix which命令?


4
whereWhere-ObjectPowershell中Commandlet的别名,因此where <item>在Powershell提示符下键入不会产生任何结果。因此,此答案是完全不正确的-如第一个链接的问题中接受的答案所示,要获取DOS where,您需要输入where.exe <item>
伊恩·肯普

0

which我的PowerShell配置文件中有此高级功能:

function which {
<#
.SYNOPSIS
Identifies the source of a PowerShell command.
.DESCRIPTION
Identifies the source of a PowerShell command. External commands (Applications) are identified by the path to the executable
(which must be in the system PATH); cmdlets and functions are identified as such and the name of the module they are defined in
provided; aliases are expanded and the source of the alias definition is returned.
.INPUTS
No inputs; you cannot pipe data to this function.
.OUTPUTS
.PARAMETER Name
The name of the command to be identified.
.EXAMPLE
PS C:\Users\Smith\Documents> which Get-Command

Get-Command: Cmdlet in module Microsoft.PowerShell.Core

(Identifies type and source of command)
.EXAMPLE
PS C:\Users\Smith\Documents> which notepad

C:\WINDOWS\SYSTEM32\notepad.exe

(Indicates the full path of the executable)
#>
    param(
    [String]$name
    )

    $cmd = Get-Command $name
    $redirect = $null
    switch ($cmd.CommandType) {
        "Alias"          { "{0}: Alias for ({1})" -f $cmd.Name, (. { which cmd.Definition } ) }
        "Application"    { $cmd.Source }
        "Cmdlet"         { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
        "Function"       { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
        "Workflow"       { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
        "ExternalScript" { $cmd.Source }
        default          { $cmd }
    }
}

0

采用:

function Which([string] $cmd) {
  $path = (($Env:Path).Split(";") | Select -uniq | Where { $_.Length } | Where { Test-Path $_ } | Get-ChildItem -filter $cmd).FullName
  if ($path) { $path.ToString() }
}

# Check if Chocolatey is installed
if (Which('cinst.bat')) {
  Write-Host "yes"
} else {
  Write-Host "no"
}

或此版本,调用原始的where命令。

此版本也更好,因为它不仅限于bat文件:

function which([string] $cmd) {
  $where = iex $(Join-Path $env:SystemRoot "System32\where.exe $cmd 2>&1")
  $first = $($where -split '[\r\n]')
  if ($first.getType().BaseType.Name -eq 'Array') {
    $first = $first[0]
  }
  if (Test-Path $first) {
    $first
  }
}

# Check if Curl is installed
if (which('curl')) {
  echo 'yes'
} else {
  echo 'no'
}

0

如果您想要一个既接受管道输入又作为参数输入的命令,则应尝试以下操作:

function which($name) {
    if ($name) { $input = $name }
    Get-Command $input | Select-Object -ExpandProperty Path
}

将命令复制并粘贴到您的个人资料(notepad $profile)。

例子:

 echo clang.exe | which
C:\Program Files\LLVM\bin\clang.exe

 which clang.exe
C:\Program Files\LLVM\bin\clang.exe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.