问答中心分类: WINDOWSWindows 命令行上是否有相当于“which”的功能?
0
匿名用户 提问 1小时 前

由于我有时会遇到路径问题,其中我自己的一个 cmd 脚本被另一个程序(路径上的早期)隐藏(隐藏),我希望能够在 Windows 命令行上找到程序的完整路径,给定只是它的名字。
是否有等效于 UNIX 命令“哪个”?
在 UNIX 上,which command打印给定命令的完整路径,以便轻松查找和修复这些阴影问题。

Foredecker 回复 1小时 前

“which”在 Unix 上做什么?

Foredecker 回复 1小时 前

Foredecker:“which”在 PATH 中搜索将在 shell 提示符下键入命令时运行的可执行文件。

Foredecker 回复 1小时 前

例如,如果您安装了 5 个版本的 Java,但您不知道正在使用哪个版本,您可以键入“which java”,它会为您提供二进制文件的 PATH

Foredecker 回复 1小时 前

@Foredecker,MR 说它在 Win2k3 中的“位置”,但 Win2k3 不是问题的一部分。如果“where”不在其他 Windows 版本中,则其他答案也有效。 IMNSHO,适用于所有 Windows 版本的答案是最好的。此外,其他答案并没有错,只是不同的做法。

Foredecker 回复 1小时 前

我知道这个问题出现在 SuperUser 之前,但它可能属于那里。

Foredecker 回复 1小时 前

您可以从这里创建一个只有 90 个字节的批处理文件:blogs.msdn.com/b/oldnewthing/archive/2005/01/20/357225.aspx或者运行一个 C# 程序 – 一个链接放在上面的网站上。

Foredecker 回复 1小时 前

我发现这个批处理文件非常方便pankaj-k.net/weblog/2004/11/equivalent_of_which_in_windows.html

Foredecker 回复 1小时 前

这在其他线程中被问到:[Powershell 中 *Nix 'which' 命令的等效项?][1] [Powershell 等效于 unixwhich命令?][2] [1]:stackoverflow.com/questions/63805/…[2]:superuser.com/questions/34492/…

Foredecker 回复 1小时 前

没有which标准 Unix 中的命令。 POSIX 实用程序是type. C Shell 有一个 which 命令,有些系统将它作为外部可执行文件。例如,在 Debian Linux 上,which来自一个名为debutils.这种外部which不会“看到”shell 内置函数、别名或函数。type做;巴什的type可以选择抑制它并进行路径查找。

Foredecker 回复 1小时 前

为了说明@kaz'点,比较输出which -a pwd相对type -a pwd

25 Answers
0
paxdiablo 回答 1小时 前

虽然更高版本的 Windows 具有where命令,您也可以在 Windows XP 中使用环境变量修饰符执行此操作,如下所示:

c:\> for %i in (cmd.exe) do @echo.   %~$PATH:i
   C:\WINDOWS\system32\cmd.exe

c:\> for %i in (python.exe) do @echo.   %~$PATH:i
   C:\Python25\python.exe

您不需要任何额外的工具,而且不仅限于PATH因为您可以替换您希望使用的任何环境变量(当然是路径格式)。

而且,如果您想要一个可以处理 PATHEXT 中的所有扩展(就像 Windows 本身一样),这个可以解决问题:

@echo off
setlocal enableextensions enabledelayedexpansion

:: Needs an argument.

if "x%1"=="x" (
    echo Usage: which ^<progName^>
    goto :end
)

:: First try the unadorned filenmame.

set fullspec=
call :find_it %1

:: Then try all adorned filenames in order.

set mypathext=!pathext!
:loop1
    :: Stop if found or out of extensions.

    if "x!mypathext!"=="x" goto :loop1end

    :: Get the next extension and try it.

    for /f "delims=;" %%j in ("!mypathext!") do set myext=%%j
    call :find_it %1!myext!

:: Remove the extension (not overly efficient but it works).

:loop2
    if not "x!myext!"=="x" (
        set myext=!myext:~1!
        set mypathext=!mypathext:~1!
        goto :loop2
    )
    if not "x!mypathext!"=="x" set mypathext=!mypathext:~1!

    goto :loop1
:loop1end

:end
endlocal
goto :eof

:: Function to find and print a file in the path.

:find_it
    for %%i in (%1) do set fullspec=%%~$PATH:i
    if not "x!fullspec!"=="x" @echo.   !fullspec!
    goto :eof

它实际上返回所有可能性,但您可以很容易地调整它以适应特定的搜索规则。

Michael Ratanapintha 回复 1小时 前

嘿,我希望我已经学会了!太糟糕了,它不适用于 MS-DOS 或 Win9x(即 command.com)。 (Raymond Chen 有一个更“详细”的版本,您可以将其转换为批处理文件:blogs.msdn.com/oldnewthing/archive/2005/01/20/357225.aspx)

paxdiablo 回复 1小时 前

@Michael,如果您仍在使用 DOS 或 Win95,则在路径上查找可执行文件是至少你的问题:-)

Mawg says reinstate Monica 回复 1小时 前

Windows 将超过 .exe 识别为可执行文件。上次我编写了一个which回到 W95/DOS 时代,搜索顺序是 – 当前目录,然后是每个路径目录,对于 cmd.com,然后是 cmd.exe,然后是 cmd.bat 所以,即使是当前目录中的 cmd.bat 也会在 cmd.exe 之前执行路径中的某个地方

paxdiablo 回复 1小时 前

@mawg,原版用于您知道扩展名的地方,因为它反映了 UNIX 下的扩展名(不会发生扩展名添加技巧)。我现在添加了一个可以做你想做的事,但它不再是一个简单的命令,而是一个脚本。它首先尝试简单的命令,然后尝试每个扩展命令。希望有帮助。您可以根据自己的需要对其进行调整(例如,如果您想要与 Windows 相同的搜索顺序 – 这显示了所有可能性)。

Brad T. 回复 1小时 前

要将其转换为批处理脚本,请创建一个名为“which.bat”的文件:@echo off for %%i in (%1) do @echo. %%~$PATH:%i要将其添加到您每次运行 cmd.exe 时加载的 alias.bat 脚本中(将上述脚本放在名为 C:\usr\aliases 的新目录中):DOSKEY which=C:\usr\aliases\which.bat $*然后您可以使用 alias.bat 文件制作一个脚本来启动 cmd.exe:cmd.exe /K E:\usr\aliases\alias.bat

barlop 回复 1小时 前

值得注意的是,例子for %i in (_____) do @echo. %~$PATH:i会发现任何扩展,而不仅仅是 exe。它适用于路径中的文件 aa 或 youtube-dl.py。但是如果你把一个目录放在那里很有趣,即使它不在路径中,它也会输出它,例如for %i in (%TEMP%) do @echo. %~$PATH:i

s.ouchene 回复 1小时 前

谢谢我正在使用没有 where 命令的 Windows 7,这可以完成工作

0
shalomb 回答 1小时 前

在 PowerShell 下,Get-Command将在任何地方找到可执行文件$Env:PATH.

$ Get-Command eventvwr

CommandType   Name          Definition
-----------   ----          ----------
Application   eventvwr.exe  c:\windows\system32\eventvwr.exe
Application   eventvwr.msc  c:\windows\system32\eventvwr.msc

而且由于 powershell 让您定义别名,which可以这样定义。

$ sal which gcm   # short form of `Set-Alias which Get-Command`
$ which foo
...

电源外壳命令不仅仅是可执行文件(.exe,.ps1, ETC)。它们也可以是 cmdlet、函数、别名、自定义的可执行后缀$Env:PATHEXT, ETC。Get-Command能够找到并列出所有这些命令(非常类似于 Bash 的type -a foo)。仅此一项就比where.exe,which.exe等,通常仅限于查找可执行文件。
仅使用部分名称查找可执行文件

$ gcm *disk*

CommandType     Name                             Version    Source
-----------     ----                             -------    ------
Alias           Disable-PhysicalDiskIndication   2.0.0.0    Storage
Alias           Enable-PhysicalDiskIndication    2.0.0.0    Storage
Function        Add-PhysicalDisk                 2.0.0.0    Storage
Function        Add-VirtualDiskToMaskingSet      2.0.0.0    Storage
Function        Clear-Disk                       2.0.0.0    Storage
Cmdlet          Get-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          New-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          Remove-PmemDisk                  1.0.0.0    PersistentMemory
Application     diskmgmt.msc                     0.0.0.0    C:\WINDOWS\system32\diskmgmt.msc
Application     diskpart.exe                     10.0.17... C:\WINDOWS\system32\diskpart.exe
Application     diskperf.exe                     10.0.17... C:\WINDOWS\system32\diskperf.exe
Application     diskraid.exe                     10.0.17... C:\WINDOWS\system32\diskraid.exe
...

查找自定义可执行文件
与 UNIX 不同,其中可执行文件是带有可执行文件 (+x) 位设置,Windows 上的可执行文件是存在于指定目录之一中的文件$PATH环境。其文件名后缀在$PATHEXT环境。变量(默认为.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL)。
作为Get-Command也尊重这个环境。变量,它可以扩展为列出自定义可执行文件。例如

$ $Env:PATHEXT="$Env:PATHEXT;.dll;.ps1;.psm1;.py"     # temporary assignment, only for this shell's process

$ gcm user32,kernel32,*WASM*,*http*py

CommandType     Name                        Version    Source
-----------     ----                        -------    ------
ExternalScript  Invoke-WASMProfiler.ps1                C:\WINDOWS\System32\WindowsPowerShell\v1.0\Invoke-WASMProfiler.ps1
Application     http-server.py              0.0.0.0    C:\Users\ME\AppData\Local\Microsoft\WindowsApps\http-server.py
Application     kernel32.dll                10.0.17... C:\WINDOWS\system32\kernel32.dll
Application     user32.dll                  10.0.17... C:\WINDOWS\system32\user32.dll

Get-Command更多选项和示例。

Maximilian Burszley 回复 1小时 前

它发现的不仅仅是可执行文件。它还捕获命令文件

shalomb 回复 1小时 前

@TheIncorrigible1 – 如果你的意思是命令文件比如批处理文件(.BAT,.CMD等),它们被认为是可执行的,因为它们的扩展名在PATHEXT变量(默认为PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL)。其他可执行类型(例如.py,.rb等)可以通过添加文件扩展名并创建可执行关联来添加assoc/ftype– 例如docs.python.org/3.3/using/…

ScriptAutomate 回复 1小时 前

老实说,现在是 2020 年,这应该被选为最佳答案,因为最初的答案是在 2008 年发布的。时代变了。 PowerShell 是一种方式,尤其是这个答案现在对于 PowerShell 存在的任何地方都是跨平台的。

0
cmcginty 回答 1小时 前

在 Windows PowerShell 中:

set-alias which where.exe
0
RexE 回答 1小时 前

如果您安装了 PowerShell(我推荐),则可以使用以下命令作为大致等效命令(将 programName 替换为可执行文件的名称):

($Env:Path).Split(";") | Get-ChildItem -filter programName*

更多在这里:我的曼维奇! PowerShell 哪个

scobi 回复 1小时 前

我一直在寻找这个精确的 powershell 命令。我一直在使用 where.exe,但在解析其输出时不得不处理错误代码远不如原生 powershell 解决方案。谢谢!

Craig Tullis 回复 1小时 前

($Env:Path).Split(";") | Get-ChildItem -filter programName*很容易打字… 😉

dragon788 回复 1小时 前

如果您的路径中有一个通常由系统解析的变量(又名 %JAVA_HOME%),这也会失败。

Asfand Qazi 回复 1小时 前

我无法让 which.exe 工作,我试过了,它工作。

ScriptAutomate 回复 1小时 前

gcm答案将是今天更好地使用 PowerShell:stackoverflow.com/a/27140194/5340149

0
Ferruccio 回答 1小时 前

GnuWin32工具有which,以及一大堆其他 Unix 工具。