Me gustaría saber qué versión de un ejecutable utiliza el shell CMD. En cualquier shell de Unix, usaría which
para encontrarlo.¿Cuál es el equivalente cmd/powershell de `which` en bash?
¿Hay un comando equivalente en uno de los shells de Windows?
Me gustaría saber qué versión de un ejecutable utiliza el shell CMD. En cualquier shell de Unix, usaría which
para encontrarlo.¿Cuál es el equivalente cmd/powershell de `which` en bash?
¿Hay un comando equivalente en uno de los shells de Windows?
Varios.
where
es un equivalente directo:
C:\Users\Joey>where cmd
C:\Windows\System32\cmd.exe
Nótese que en PowerShell where
sí mismo es un alias para Where-Object
, por lo tanto es necesario utilizar where.exe
en PowerShell.
En cmd
también se puede utilizar for
:
C:\Users\Joey>for %x in (powershell.exe) do @echo %~$PATH:x
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
En PowerShell tiene Get-Command
y su alias gcm
que hace lo mismo si se pasa un argumento (pero también funciona para los alias, cmdlets y funciones en PowerShell):
PS C:\Users\Joey> Get-Command where
CommandType Name Definition
----------- ---- ----------
Alias where Where-Object
Application where.exe C:\Windows\system32\where.exe
El primer comando devuelto es el que se ejecutará.
Por alguna razón, 'where' no funcionó para mí en absoluto (no imprimí nada e inmediatamente lo dejé), pero 'gcm' funcionó muy bien. – Hassan
@Hassan: como puede deducir de la salida de muestra de 'Get-Command where' en PowerShell,' where' es en realidad un alias para 'Where-Object', que tiene prioridad sobre' where.exe'. Para ejecutar 'where.exe', debe ingresar' where.exe'. Al menos en PowerShell. – Joey
Oh. Sí, ese era el problema. ¡Gracias! – Hassan
El comando WHERE
no del todo es lo mismo que Unix which
porque contiene todos los archivos coincidentes que se encuentran en el directorio o PATH actual. Como dice Joey, el primero que aparece es el que ejecuta. Es simple crear un script por lotes que solo devolverá el primero encontrado.
@echo off
for /f "delims=" %%F in ('where %1') do (
echo %%F
exit /b
)
Pero WHERE
es relativamente lento.
A continuación se muestra un script WHICH.BAT que es más rápido y lo hace un poco más. Utiliza una amplia y diferida alternancia de expansión porque: 1) El porcentaje de% de RUTA en expansión no es confiable si hay caracteres especiales sin comillas. 2) La expansión de las variables FOR mientras la expansión retrasada está habilitada corrompe los valores que contienen !
.
::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
ACTUALIZACIÓN
tuve que modificar significativamente el guión anterior, ya que fue enumerando incorrectamente un comando interno como externo, si no pasó a existir un archivo EXE con el mismo nombre de raíz en algún lugar del camino.
Sí, hay http://stackoverflow.com/questions/304319/is-there-an-equivalent-of-which-on-windows/304441#304441 – paxdiablo