由于我有时会遇到路径问题,我自己的一个cmd脚本被另一个程序隐藏(隐藏)(路径前面),所以我希望能够在Windows命令行上找到程序的完整路径,只要给出它的名称。

是否有与UNIX命令“which”等效的命令?

在UNIX上,哪个命令打印给定命令的完整路径,以便轻松查找和修复这些阴影问题。


当前回答

Cygwin是一个解决方案。如果您不介意使用第三方解决方案,那么Cygwin就是您的选择。

Cygwin在Windows环境中为您提供了*nix的舒适性(您可以在Windows命令shell中使用它,也可以选择使用*nix shell)。它为您提供了一整套适用于Windows的*nix命令(如),您可以将该目录包含在PATH中。

其他回答

在PowerShell下,Get命令将在$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让我们定义别名,可以这样定义。

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

PowerShell命令不仅仅是可执行文件(.exe、.ps1等)。它们也可以是cmdlet、函数、别名、在$Env:PATHEXT中设置的自定义可执行后缀等。Get Command能够查找并列出所有这些命令(与Bash的类型-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不同,在UNIX中,可执行文件是设置了可执行(+x)位的文件,而windows上的可执行文件则是$PATH env中指定的一个目录中的文件。其文件名后缀在$PATHEXT env中命名的变量。变量(默认为.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL)。

作为Get Command,也将此env作为荣誉。变量,它可以扩展为列出自定义可执行文件。例如

$ $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

有关更多选项和示例,请参见获取命令。

虽然较新版本的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

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

我在互联网上找到的Unix Win32端口没有一个是令人满意的,因为它们都有一个或多个缺点:

不支持Windows PATHEXT变量。(它定义了在扫描路径之前隐式添加到每个命令的扩展列表,以及顺序。)(我使用了很多tcl脚本,没有公开可用的工具可以找到它们。)不支持cmd.exe代码页,这会使它们错误地显示带有非ascii字符的路径。(我对此非常敏感,我的名字中有一个ç:-)cmd.exe和PowerShell命令行中不支持不同的搜索规则。(没有公开可用的工具可以在PowerShell窗口中找到.ps1脚本,但在cmd窗口中找不到!)

所以我最终写了我自己的,这正确地支持了以上所有内容。

此处可用:http://jf.larvoire.free.fr/progs/which.exe

下面是一个我创建的函数,用于查找与Unix命令“WHITE”类似的可执行文件`

app_path_func.cmd:

@ECHO OFF
CLS

FOR /F "skip=2 tokens=1,2* USEBACKQ" %%N IN (`reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\%~1" /t REG_SZ  /v "Path"`) DO (
 IF /I "%%N" == "Path" (
  SET wherepath=%%P%~1
  GoTo Found
 )
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%PROGRAMFILES%" %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%PROGRAMFILES(x86)%" %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%WINDIR%" %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

:Found
SET %2=%wherepath%
:End

测试:

@ECHO OFF
CLS

CALL "app_path_func.cmd" WINWORD.EXE PROGPATH
ECHO %PROGPATH%

PAUSE

结果:

C:\Program Files (x86)\Microsoft Office\Office15\
Press any key to continue . . .

https://www.freesoftwareservers.com/display/FREES/Find+可执行文件+通过+批处理+-+Microsoft+Office+示例+-+WINWORD+-+查找+Microsoft+Office+路径

从这里获取unxutils:http://sourceforge.net/projects/unxutils/

在windows平台上的黄金,将所有漂亮的unix实用程序放在标准的windows DOS上。多年来一直在使用它。

它包含一个“which”。注意,它是区分大小写的。

注意:要安装它,请在某个地方爆炸拉链并添加。。。\将xUtils\usr\local\wbin\解压缩到系统路径env变量。