Есть ли эквивалент "which" в командной строке Windows?

поскольку у меня иногда возникают проблемы с путем, где один из моих собственных сценариев cmd скрыт (затенен) другой программой (ранее на пути), я хотел бы иметь возможность найти полный путь к программе в командной строке Windows, учитывая только ее имя.

есть ли эквивалент команды UNIX "which"?

в UNIX,which command печатает полный путь данной команды, чтобы легко найти и устранить эти проблемы затенения.

22 ответов


Windows Server 2003 и более поздние версии (т. е. все, что после Windows XP 32 бит) предоставляют where.exe программа, которая делает некоторые из того, что which делает, хотя он соответствует всем типам файлов, а не только исполняемые команды. (Он не соответствует встроенным командам оболочки, таким как cd.) Он даже будет принимать подстановочные знаки, так что where nt* находит все файлы в папке %PATH% и текущий каталог, чьи имена начинаются с nt.

попробовать where /? за помощью.

обратите внимание, что Windows PowerShell определяет where в качестве псевдонима для the , так что если вы хотите where.exe, вам нужно ввести полное имя вместо того, чтобы опустить


в то время как более поздние версии 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

он фактически возвращает все возможности, но вы можете настроить его довольно легко для конкретных правил поиска.


В PowerShell get-command найдет исполняемые файлы в любом месте $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, функции, псевдонимы, файлы с пользовательскими расширениями исполняемых файлов через $Env:PATHEXT, etc определенный для текущей оболочки (довольно сродни bash type -a foo) - что делает его лучше, чем другие инструменты, такие как where.exe, which.exe и т. д., которые не знают об этих командах PowerShell.

вы можете быстро настроить псевдоним с sal which gcm (короткая форма set-alias which get-command).


в Windows powershell:

set-alias which where.exe

Если у Вас установлен PowerShell (что я рекомендую), вы можете использовать следующую команду в качестве грубого эквивалента (замените имя программы для имени исполняемого файла):

($Env:Path).Split(";") | Get-ChildItem -filter programName*

подробнее здесь: http://www.codeassassin.com/blog/PermaLink,guid,fd1967d1-f844-4e29-82e2-f2d6424b4ef9.aspx


на GnuWin32 инструменты which, наряду с целым рядом других инструментов Unix.


В Windows CMD which звонки where:

$ where php
C:\Program Files\PHP\php.exe

удивлен, что никто не упомянул cygwin как решение пока. Если вы не возражаете использовать стороннее решение, то cygwin-это путь.

Cygwin дает вам комфорт *nix в среде Windows (и вы можете использовать его в командной оболочке Windows или использовать оболочку *nix по вашему выбору). Он дает вам целый ряд команд *nix (например,which) для Windows, и вы можете просто включить этот каталог в ваш PATH.


в PowerShell, это gcm, который дает подробную информацию о других командах. Если вы хотите получить только путь к исполняемому файлу, используйте .Source.

например: gcm git или (gcm git).Source

лакомые кусочки:

  • доступно для Windows XP.
  • доступно с PowerShell 1.0.
  • gcm - это псевдоним

идите получить unxutils отсюда:http://sourceforge.net/projects/unxutils/

золото на платформах windows, ставит все хорошие утилиты unix на стандартную Windows DOS. Использую его в течение многих лет.

Он имеет "который" включен. Обратите внимание, что он чувствителен к регистру.

NB: чтобы установить его, взорвать zip где-нибудь и добавить ...\UnxUtils\usr\local\wbin\ к переменной env системного пути.


у меня есть функция в моем профиле PowerShell с именем "which"

function which {
    get-command $args[0]| format-list
}

вот как выглядит вывод:

PS C:\Users\fez> which python


Name            : python.exe
CommandType     : Application
Definition      : C:\Python27\python.exe
Extension       : .exe
Path            : C:\Python27\python.exe
FileVersionInfo : File:             C:\Python27\python.exe
                  InternalName:
                  OriginalFilename:
                  FileVersion:
                  FileDescription:
                  Product:
                  ProductVersion:
                  Debug:            False
                  Patched:          False
                  PreRelease:       False
                  PrivateBuild:     False
                  SpecialBuild:     False
                  Language:

Не знаю, поможет ли это. Опубликовано как ответ, потому что я не знаю, как форматировать код в комментарии (помогите?)

Если вы можете найти бесплатный компилятор pascal, вы можете скомпилировать это, или напишите Мне, и я могу попытаться выкопать его, или отправить обратно exe или опубликовать его где-нибудь. Я отправляю код, как бы плохо это ни было, потому что, по крайней мере, он работает и показывает необходимый алгоритм.

program Whence (input,output);
  Uses Dos, my_funk;
  Const program_version = '1.00';
        program_date    = '17 March 1994';
  VAR   path_str          : string;
        command_name      : NameStr;
        command_extension : ExtStr;
        command_directory : DirStr;
        search_dir        : DirStr;
        result            : DirStr;


  procedure Check_for (file_name : string);
    { check existance of the passed parameter. If exists, then state so   }
    { and exit.                                                           }
  begin
    if Fsearch(file_name,'') <> '' then
    begin
      WriteLn('Dos command = ',Fexpand(file_name));
      Halt(0);    { structured ? whaddayamean structured ? }
    end;
  end;

  function Get_next_dir : DirStr;
    { Returns the next directory from the path variable, truncating the   }
    { variable every time. Implicit input (but not passed as parameter)   }
    { is, therefore, path_str                                             }
    var  semic_pos  : Byte;

  begin
      semic_pos  := Pos(';',path_str);
      if (semic_pos = 0) then
      begin
        Get_next_dir := '';
        Exit;
      end;

      result       := Copy(Path_str,1,(semic_pos - 1));  { return result   }
      { hmm! although *I* never reference a Root drive (my directory tree) }
      { is 1/2 way structured), some network logon software which I run    }
      { does (it adds Z:\ to the path). This means that I have to allow    }
      { path entries with & without a terminating backslash. I'll delete   }
      { anysuch here since I always add one in the main program below.     }
      if (Copy(result,(Length(result)),1) = '\') then
         Delete(result,Length(result),1);

      path_str     := Copy(path_str,(semic_pos + 1),
                                 (length(path_str) - semic_pos));
      Get_next_dir := result;
  end;  { of function get_next_dir }

begin
  { the following is a kludge which makes the function Get_next_dir easier  }
  { to implement. By appending a semi-colon to the end of the path         }
  { Get_next_dir doesn't need to handle the special case of the last entry }
  { which normally doesn't have a semic afterwards. It may be a kludge,    }
  { but it's a documented kludge (you might even call it a refinement).    }
  path_str := GetEnv('Path') + ';';

  if (paramCount = 0) then
  begin
    WriteLn('Whence : V',program_version,' from ',program_date);
    Writeln;
    WriteLn('Usage  : WHENCE command[.extension]');
    WriteLn;
    WriteLn('Whence is a ''find file''type utility witha difference');
    Writeln('There are are already more than enough of those   :-)');
    Write  ('Use Whence when you''re not sure where a command which you ');
    WriteLn('want to invoke');
    WriteLn('actually resides.');
    Write  ('If you intend to invoke the command with an extension e.g ');
    Writeln('"my_cmd.exe param"');
    Write  ('then invoke Whence with the same extension e.g ');
    WriteLn('"Whence my_cmd.exe"');
    Write  ('otherwise a simple "Whence my_cmd" will suffice; Whence will ');
    Write  ('then search the current directory and each directory in the ');
    Write  ('for My_cmd.com, then My_cmd.exe and lastly for my_cmd.bat, ');
    Write  ('just as DOS does');
    Halt(0);
  end;

  Fsplit(paramStr(1),command_directory,command_name,command_extension);
  if (command_directory <> '') then
  begin
WriteLn('directory detected *',command_directory,'*');
    Halt(0);
  end;

  if (command_extension <> '') then
  begin
    path_str := Fsearch(paramstr(1),'');    { current directory }
    if   (path_str <> '') then WriteLn('Dos command = "',Fexpand(path_str),'"')
    else
    begin
      path_str := Fsearch(paramstr(1),GetEnv('path'));
      if (path_str <> '') then WriteLn('Dos command = "',Fexpand(path_str),'"')
                          else Writeln('command not found in path.');
    end;
  end
  else
  begin
    { O.K, the way it works, DOS looks for a command firstly in the current  }
    { directory, then in each directory in the Path. If no extension is      }
    { given and several commands of the same name exist, then .COM has       }
    { priority over .EXE, has priority over .BAT                             }

    Check_for(paramstr(1) + '.com');     { won't return if file is found }
    Check_for(paramstr(1) + '.exe');
    Check_for(paramstr(1) + '.bat');


    { not in current directory, search thru path .... }

    search_dir := Get_next_dir;

    while (search_dir <> '') do
    begin
       Check_for(search_dir + '\' + paramstr(1) + '.com');
       Check_for(search_dir + '\' + paramstr(1) + '.exe');
       Check_for(search_dir + '\' + paramstr(1) + '.bat');
       search_dir := Get_next_dir;
    end;


    WriteLn('DOS command not found : ',paramstr(1));
  end;
end.

не в наличии Windows, но это предусмотрено сервисы для Unix и есть несколько простых пакетных скриптов, плавающих вокруг, которые выполняют то же самое, что и это этот.


лучшая версия этого, которую я нашел в Windows, - это утилита Джозефа Ньюкомера "whereis", которая доступна (с источником) из его сайт.

статью о разработке "whereis"стоит прочитать.


Я создал инструмент, похожий на NED Batchelder:

Поиск .dll и .exe файлы в пути

хотя мой инструмент предназначен главным образом для поиска различных версий dll, он показывает больше информации (дата, размер, версия), но не использует PATHEXT (я надеюсь скоро обновить свой инструмент).


ни один из портов Win32 Unix, которые я мог бы найти в Интернете, не является satistactory, потому что все они имеют один или несколько из этих недостатков:

  • нет поддержки переменной Windows PATHEXT. (Который определяет список расширений, имплицитно добавленных к каждой команде перед сканированием пути, и в каком порядке.) (Я использую много сценариев tcl, и нет общедоступного инструмента, который мог бы их найти.)
  • нет поддержки cmd.exe кодовые страницы, что делает их неправильно отображать пути с символами, отличными от ascii. (Я очень чувствителен к этому, с ç в моем первом имени : -))
  • нет поддержки отдельных правил поиска в cmd.exe и командная строка PowerShell. (Ни один общедоступный инструмент не найдет .PS1 скрипты в окне PowerShell, но не в окне cmd!)

поэтому я в конце концов написал свой собственный, который правильно поддерживает все вышесказанное.

доступные там: http://jf.larvoire.free.fr/progs/which.exe


этот пакетный файл использует обработку переменных CMD для поиска команды, которая будет выполнена в пути. Примечание: текущий каталог всегда выполняется до пути) и в зависимости от того, какой вызов API используется, другие местоположения ищутся до/после пути.

@echo off
echo. 
echo PathFind - Finds the first file in in a path
echo ======== = ===== === ===== ==== == == = ====
echo. 
echo Searching for %1 in %path%
echo. 
set a=%~$PATH:1
If "%a%"=="" (Echo %1 not found) else (echo %1 found at %a%)

посмотреть set /? за помощью.


вы можете сначала установить git изhttps://git-scm.com/download/win затем откройте Git bash и введите

which app-name

TCC и TCC / LE из JPSoft являются CMD.EXE замены, которые добавляют значительную функциональность. Что касается вопроса ОП,which является встроенной командой для процессоров команд семейства TCC.


для пользователей XP (у которых нет where команда встроенная), я написал команду" где нравится " как rubygem под названием whichr

чтобы установить его, установите ruby

затем

gem install whichr

запустить его как

c:\>whichr cmd_here


Я использую GOW (Gnu на Windows), который является легкой версией cygwin. Вы можете захватить его из github здесь.

Gow (Gnu на Windows) является легкой альтернативой Cygwin. Он использует удобный установщик Windows, который устанавливает около 130 чрезвычайно полезные приложения UNIX с открытым исходным кодом, скомпилированные как собственный win32 двоичный код. Он разработан, чтобы быть как можно меньше, около 10 МБ, как в отличие от Cygwin, который может работать более 100 МБ в зависимости от опции. - О Описании (Brent R. Matzelle)

скриншот списка команд, включенных в GOW.

enter image description here


я использовал which модуль от npm довольно долго, и он работает очень хорошо:https://www.npmjs.com/package/which Это отличная многоплатформенная альтернатива.

теперь я переключился на which Это поставляется с Git. Просто добавьте в свой путь /usr/bin путь от Git, который обычно находится в C:\Program Files\Git\usr\bin\which.exe. The which двоичный будет в C:\Program Files\Git\usr\bin\which.exe. Это быстрее, а также работает, как ожидалось.