Есть ли эквивалент «который» в командной строке Windows?

2194
задан Wolf 25 January 2018 в 01:53
поделиться

10 ответов

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

Попытка where /? для справки.

Примечание, которое Windows PowerShell определяет where как псевдоним для [1 111] Where-Object cmdlet, поэтому если Вы хотите where.exe, необходимо ввести полное имя вместо того, чтобы опустить .exe расширение.

2401
ответ дан rogerdpack 25 January 2018 в 01:53
поделиться
  • 1
    На самом деле инициализация указателя на ПУСТОЙ УКАЗАТЕЛЬ имеет по крайней мере один значительный недостаток: это может препятствовать тому, чтобы компилятор предупредил Вас о неинициализированных переменных. Если логика Вашего кода на самом деле явно не обрабатывает то значение для указателя (т.е. если (nPtr == ПУСТОЙ УКАЗАТЕЛЬ) dosomething...) it' s лучше для отъезда его как есть. – Eric 16 November 2012 в 08:18

Лучшая версия этого, которое я нашел в Windows, является "whereis" утилитой Joseph Newcomer, которая доступна (с источником) от его сайт .

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

7
ответ дан Tim Lesher 25 January 2018 в 01:53
поделиться
  • 1
    @DavidSchwartz ну, который звучит разумным... Спасибо за Ваш комментарий я рассмотрю это в будущем!:) +1 – mozzbozz 5 June 2014 в 11:37

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

7
ответ дан Robert Gamble 25 January 2018 в 01:53
поделиться
  • 1
    Или используйте макрос - никакая потребность в от указателя к указателю тот путь. – Tal Pressman 22 June 2009 в 16:45

Я создал инструмент, подобный Ned Batchelder:

Поиск .dll и .exe файлы в ПУТИ

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

5
ответ дан Michał Niklas 25 January 2018 в 01:53
поделиться

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

36
ответ дан Ferruccio 25 January 2018 в 01:53
поделиться

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

($Env:Path).Split(";") | Get-ChildItem -filter programName*
[еще 114] здесь: Мой Manwich! PowerShell, Который

39
ответ дан Peter Mortensen 25 January 2018 в 01:53
поделиться

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

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

281
ответ дан paxdiablo 25 January 2018 в 01:53
поделиться

Просто должны отправить один пакетный файл лайнера этого Windows:

C:>type wh.cmd
@for %%f in (%*) do for %%e in (%PATHEXT% .dll .lnk) do for %%b in (%%f%%e) do for %%d in (%PATH%) do if exist %%d\%%b echo %%d\%%b

тест А:

C:>wh ssh
C:\cygwin64\bin\ssh.EXE
C:\Windows\System32\OpenSSH\\ssh.EXE

Не совсем острота, если Вы переносите код в setlocal enableextensions и endlocal.

1
ответ дан 22 November 2019 в 19:55
поделиться

Возьмите unxutils отсюда: http://sourceforge.net/projects/unxutils/

gold на платформах windows, ставит все хорошие unix утилиты на стандартный windows DOS. Пользуюсь ей уже много лет.

В нем есть 'which'. Обратите внимание, что он чувствителен к регистру.

NB: для установки взорвите zip и добавьте ...\UnxUtils\usr\local\wbin\ в переменную env вашего системного пути.

10
ответ дан 22 November 2019 в 19:55
поделиться

Если вы можете найти бесплатный компилятор Pascal, вы можете скомпилировать его. По крайней мере, он работает и показывает необходимый алгоритм.

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 existence 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 through 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.
8
ответ дан 22 November 2019 в 19:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: