Whats the cmd/powershell equivalent of `which` on bash?

I would like to find out which version of an executable the CMD shell uses. In any unix shell, I would use which to find it.

Is there an equivalent command in one of the Windows shells?


Various.

  • where is a direct equivalent:

    C:UsersJoey>where cmd
    C:WindowsSystem32cmd.exe
    

    Note that in PowerShell where itself is an alias for Where-Object , thus you need to use where.exe in PowerShell.

  • In cmd you can also use for :

    C:UsersJoey>for %x in (powershell.exe) do @echo %~$PATH:x
    C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
    
  • In PowerShell you have Get-Command and its alias gcm which does the same if you pass an argument (but also works for aliases, cmdlets and functions in PowerShell):

    PS C:UsersJoey> Get-Command where
    
    CommandType     Name          Definition
    -----------     ----          ----------
    Alias           where         Where-Object
    Application     where.exe     C:Windowssystem32where.exe
    

    The first returned command is the one that would be executed.


  • The WHERE command is not quite the same as unix which because it lists all matching files found in the current directory or PATH. As Joey says, the first one listed is the one that what execute. It is simple to create a batch script that will only return the first one found.

    @echo off
    for /f "delims=" %%F in ('where %1') do (
      echo %%F
      exit /b
    )
    

    But WHERE is relatively slow.

    Below is a WHICH.BAT script that is faster and does a bit more. It uses extensive delayed expansion toggling because: 1) Expanding %PATH% is unreliable if there are unquoted special characters. 2) Expanding FOR variables while delayed expansion is enabled corrupts values that contain ! .

    ::WHICH.BAT  CommandName  [ReturnVar]
    ::
    ::  Determines the full path of the file that would execute if
    ::  CommandName were executed.
    ::
    ::  The result is stored in variable ReturnVar, or else it is
    ::  echoed to stdout if ReturnVar is not specified.
    ::
    ::  If no file is found, then an error message is echoed to stderr.
    ::
    ::  The ERRORLEVEL is set to one of the following values
    ::    0 - Success: A matching file was found
    ::    1 - CommandName is an internal command
    ::    2 - No file was found and CommandName is not an internal command
    ::    3 - Improper syntax - no CommandName specified
    ::
    @echo off
    setlocal disableDelayedExpansion
    
    set "file=%~1"
    setlocal enableDelayedExpansion
    
    if not defined file (
      >&2 echo Syntax error: No CommandName specified
      exit /b 3
    )
    
    
    :: test for internal command
    echo(!file!|findstr /i "[^abcdefghijklmnopqrstuvwxyz]" >nul || (
      set "empty=!temp!emptyFolder"
      md "!empty!" 2>nul
      del /q "!empty!*" 2>nul >nul
      setlocal
      pushd "!empty!"
      set path=
      (call )
      !file! /? >nul 2>nul
      if not errorlevel 9009 (
        >&2 echo "!file!" is an internal command
        popd
        exit /b 1
      )
      popd
      endlocal
    )
    
    
    :: test for external command
    set "noExt="
    if "%~x1" neq "" if "!PATHEXT:%~x1=!" neq "!PATHEXT!" set noExt="";
    set "modpath=.;!PATH!"
    @for %%E in (%noExt%%PATHEXT%) do @for %%F in ("!file!%%~E") do (
      setlocal disableDelayedExpansion
      if not "%%~$modpath:F"=="" if not exist "%%~$modpath:F" (
        endlocal & endlocal & endlocal
        if "%~2"=="" (echo %%~$modpath:F) else set "%~2=%%~$modpath:F"
        exit /b 0
      )
      endlocal
    )
    endlocal
    
    
    >&2 echo "%~1" is not a valid command
    exit /b 2
    

    UPDATE

    I had to significantly modify the script above because it was incorrectly listing an internal command as external if there happened to exist an exe file with the same root name somewhere in the PATH.

    链接地址: http://www.djcxy.com/p/30264.html

    上一篇: 如何用PyCharm运行Pylint

    下一篇: 在bash上的`which`的cmd / powershell相当于什么?