2012-06-13 22 views

Trả lời

50

Khác nhau.

  1. where là một tương đương trực tiếp:

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

    Lưu ý rằng trong PowerShell where chính nó là một bí danh cho Where-Object, do đó bạn cần phải sử dụng where.exe trong PowerShell.

  2. Trong cmd bạn cũng có thể sử dụng for:

    C:\Users\Joey>for %x in (powershell.exe) do @echo %~$PATH:x 
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 
    
  3. Trong PowerShell bạn có Get-Command và bí danh của nó gcm mà không giống nhau nếu bạn vượt qua một cuộc tranh cãi (nhưng cũng làm việc cho bí danh, cmdlet và chức năng trong PowerShell):

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

    Lệnh trả lại đầu tiên là lệnh sẽ được thực thi.

+1

Vì một số lý do, 'where' không hoạt động cho tôi ở tất cả (in không có gì và ngay lập tức bỏ thuốc lá), nhưng 'gcm' làm việc rất tốt. – Hassan

+1

@Hassan: Khi bạn có thể thu thập từ đầu ra mẫu của 'Get-Command where' trên PowerShell,' where' thực sự là một bí danh cho 'Where-Object', được ưu tiên hơn' where.exe'. Để chạy 'where.exe', bạn phải nhập' where.exe'. Ít nhất trong PowerShell. – Joey

+0

Ồ. Vâng, đó là vấn đề. Cảm ơn! – Hassan

4

Lệnh WHERE là không hoàn toàn giống như unix which vì nó sẽ liệt kê tất cả các file phù hợp được tìm thấy trong thư mục hiện hành hoặc PATH. Như Joey nói, cái đầu tiên được liệt kê là cái mà cái thực thi. Rất đơn giản để tạo tập lệnh theo lô sẽ chỉ trả lại tập lệnh đầu tiên được tìm thấy.

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

Nhưng WHERE tương đối chậm.

Dưới đây là tập lệnh WHICH.BAT nhanh hơn và nhiều hơn một chút. Nó sử dụng mở rộng chậm trễ mở rộng vì: 1) Mở rộng% PATH% là không đáng tin cậy nếu có các ký tự đặc biệt không được trích dẫn. 2) Mở rộng CHO các biến trong khi mở rộng trễ được kích hoạt làm hỏng các giá trị có chứa !.

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

CẬP NHẬT

tôi đã phải sửa đổi đáng kể kịch bản ở trên vì nó đã sai niêm yết một lệnh nội bộ như bên ngoài nếu có xảy ra tồn tại một tập tin exe với tên cùng một gốc ở đâu đó trong PATH.