Quel est l'équivalent cmd/powershell de 'which' sur bash?

Je voudrais savoir quelle version d'un exécutable le shell CMD utilise. Dans n'importe quel shell unix, j'utiliserais which pour le trouver.

Existe-t-il une commande équivalente dans L'un des shells de Windows?

32
demandé sur bastibe 2012-06-13 10:51:51

2 réponses

Divers.

  1. where est un équivalent direct:

    C:\Users\Joey>where cmd
    C:\Windows\System32\cmd.exe
    

    Notez que dans PowerShell where lui-même est un alias pour Where-Object, donc vous devez utiliser where.exe dans PowerShell.

  2. Dans cmd vous pouvez aussi utiliser for:

    C:\Users\Joey>for %x in (powershell.exe) do @echo %~$PATH:x
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    
  3. Dans PowerShell vous avez Get-Command et son alias gcm qui fait la même chose si vous passez un argument (mais fonctionne également pour les alias, les cmdlets et les fonctions dans PowerShell):

    PS C:\Users\Joey> Get-Command where
    
    CommandType     Name          Definition
    -----------     ----          ----------
    Alias           where         Where-Object
    Application     where.exe     C:\Windows\system32\where.exe
    

    La première commande renvoyée est celui qui serait exécuté.

58
répondu Joey 2012-06-13 06:53:23

La commande WHERE n'est pas tout à fait la même que unix which car elle répertorie tous les fichiers correspondants trouvés dans le répertoire ou le chemin courant. Comme le dit Joey, le premier répertorié est celui qui exécute. Il est simple de créer un script batch qui ne retournera que le premier trouvé.

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

, Mais WHERE est relativement lente.

Ci-dessous est un qui.Bat script qui est plus rapide et fait un peu plus. Il utilise un basculement d'expansion retardée étendu car: 1) L'expansion de % PATH% n'est pas fiable si il y a des caractères spéciaux non cités. 2) L'expansion des variables pendant que l'expansion retardée est activée corrompt les valeurs qui contiennent !.

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

Mise à JOUR

J'ai dû modifier de manière significative le script ci-dessus car il listait incorrectement une commande interne comme externe s'il existait un fichier exe avec le même nom racine quelque part dans le chemin.

4
répondu dbenham 2014-01-15 20:05:48