desenv-web-rp.com

Existe um equivalente de 'which' na linha de comando do Windows?

Como às vezes tenho problemas de caminho, onde um dos meus próprios scripts cmd é oculto (sombreado) por outro programa (anteriormente no caminho), eu gostaria de poder encontrar o caminho completo para um programa na linha de comando do Windows, dado apenas seu nome.

Existe um equivalente ao comando UNIX 'which'?

No UNIX, which command imprime o caminho completo do comando fornecido para localizar e reparar facilmente esses problemas de sombreamento.

2107
namin

O Windows Server 2003 e versões posteriores (ou seja, qualquer coisa após o Windows XP 32 bits) fornecem o programa where.exe, que faz parte do que which faz, embora corresponda a todos os tipos de arquivos, não apenas a comandos executáveis. (Ele não corresponde a comandos internos do Shell como cd.) Ele até aceita curingas, então where nt* encontra todos os arquivos em seu %PATH% e diretório atual cujos nomes começam com nt.

Tente where /? para ajuda.

Observe que o Windows PowerShell define where como um alias para o cmdlet Where-Object , portanto, se você quiser where.exe, é necessário digitar o nome completo em vez de omitir a extensão .exe.

2313
Michael Ratanapintha

Embora versões posteriores do Windows tenham um comando where, você também pode fazer isso com o Windows XP usando os modificadores de variáveis ​​de ambiente, da seguinte maneira:

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

Você não precisa de nenhuma ferramenta extra e não está limitado a PATH, já que você pode substituir qualquer variável de ambiente (no formato de caminho, é claro) que você deseja usar.


E, se você quiser um que possa lidar com todas as extensões em PATHEXT (como o próprio Windows faz), este faz o truque:

@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

Ele realmente retorna todas as possibilidades, mas você pode ajustá-lo facilmente para regras de pesquisa específicas.

274
paxdiablo

Sob PowerShell, Get-Command encontrará executáveis ​​em qualquer lugar em $Env:PATH.

Get-Command eventvwr

CommandType   Name          Definition
-----------   ----          ----------
Application   eventvwr.exe  c:\windows\system32\eventvwr.exe
Application   eventvwr.msc  c:\windows\system32\eventvwr.msc

Ele também encontra cmdlets, funções, aliases, arquivos com extensões de executáveis ​​personalizados via $Env:PATHEXT, etc. definidos para o Shell atual (bem parecido com type -a foo do Bash) - tornando-o melhor do que outras ferramentas como where.exe, which.exe, etc. desconhecem esses comandos do PowerShell.

Encontrando executáveis ​​usando apenas parte do nome

gcm *disk*

CommandType     Name                             Version    Source
-----------     ----                             -------    ------
Alias           Disable-PhysicalDiskIndication   2.0.0.0    Storage
Alias           Enable-PhysicalDiskIndication    2.0.0.0    Storage
Function        Add-PhysicalDisk                 2.0.0.0    Storage
Function        Add-VirtualDiskToMaskingSet      2.0.0.0    Storage
Function        Clear-Disk                       2.0.0.0    Storage
Cmdlet          Get-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          New-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          Remove-PmemDisk                  1.0.0.0    PersistentMemory
Application     diskmgmt.msc                     0.0.0.0    C:\WINDOWS\system32\diskmgmt.msc
Application     diskpart.exe                     10.0.17... C:\WINDOWS\system32\diskpart.exe
Application     diskperf.exe                     10.0.17... C:\WINDOWS\system32\diskperf.exe
Application     diskraid.exe                     10.0.17... C:\WINDOWS\system32\diskraid.exe
...

Encontrando executáveis ​​customizados

Para encontrar outros executáveis ​​que não sejam do Windows (python, Ruby, Perl, etc), as extensões de arquivo desses executáveis ​​precisam ser adicionadas à variável ambiental PATHEXT (padrão .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL) para identificar arquivos com essas extensões na PATH como executáveis. Como Get-Command também honra esta variável, ela pode ser estendida para listar executáveis ​​customizados. por exemplo.

$Env:PATHEXT="$Env:PATHEXT;.dll;.ps1;.psm1;.py"     # temporary assignment, only for this Shell's process

gcm user32,kernel32,*WASM*,*http*py

CommandType     Name                        Version    Source
-----------     ----                        -------    ------
ExternalScript  Invoke-WASMProfiler.ps1                C:\WINDOWS\System32\WindowsPowerShell\v1.0\Invoke-WASMProfiler.ps1
Application     http-server.py              0.0.0.0    C:\Users\ME\AppData\Local\Microsoft\WindowsApps\http-server.py
Application     kernel32.dll                10.0.17... C:\WINDOWS\system32\kernel32.dll
Application     user32.dll                  10.0.17... C:\WINDOWS\system32\user32.dll

Você pode configurar rapidamente um alias com sal which gcm (forma abreviada de set-alias which get-command).

Mais informações e exemplos podem ser encontrados na ajuda online de Get-Command .

126
shalomb

No Windows PowerShell:

set-alias which where.exe
51
cmcginty

Se você tiver o PowerShell instalado (o que eu recomendo), você pode usar o seguinte comando como um equivalente aproximado (substitua programName para o nome do seu executável):

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

Mais está aqui:My Manwich! PowerShell quais

38
RexE

As GnuWin32 tools têm which, juntamente com uma enorme quantidade de outras ferramentas Unix.

33
Ferruccio

No Windows CMD, which chama where:

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

Cygwin é uma solução. Se você não se importa em usar uma solução de terceiros, então o Cygwin é o caminho a percorrer.

O Cygwin oferece o conforto do * nix no ambiente Windows (e você pode usá-lo no seu comando do Windows Shell, ou usar um * nix Shell de sua escolha). Ele fornece um host inteiro de comandos * nix (como which) para o Windows, e você pode simplesmente incluir esse diretório em sua PATH.

16
palswim

No PowerShell, é gcm, que fornece informações formatadas sobre outros comandos. Se você quiser recuperar apenas o caminho para o executável, use .Source.

Por exemplo: gcm git ou (gcm git).Source

Petiscos:

12
vulcan raven

Eu tenho uma função no meu perfil do PowerShell chamado 'which'

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

Aqui está o que a saída parece:

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

Vá buscar unxutils aqui: http://sourceforge.net/projects/unxutils/

ouro em plataformas Windows, coloca todos os utilitários Unix Nice em um DOS padrão do Windows. Estou usando isso há anos.

Tem um 'que' incluído. Note que é sensível a maiúsculas e minúsculas.

Nota: para instalá-lo, exploda o Zip em algum lugar e adicione ...\UnxUtils\usr\local\wbin\à variável de env do caminho do sistema.

9
Jon Court

Se você pode encontrar um compilador gratuito do Pascal, você pode compilar isso. Pelo menos funciona e mostra o algoritmo necessário.

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
Mawg

Não em estoque Windows, mas é fornecido pelo Serviços para Unix e há vários scripts em lote simples flutuando que realizam a mesma coisa, como este este .

7
Robert Gamble

A melhor versão disso que eu encontrei no Windows é o utilitário "whereis" de Joseph Newcomer, que está disponível (com fonte) de seu site .

O artigo sobre o desenvolvimento de "whereis" vale a pena ser lido.

7
Tim Lesher

Esse arquivo em lote usa o tratamento de variáveis ​​CMD para localizar o comando que seria executado no caminho. Nota: o diretório atual sempre é feito antes do caminho) e dependendo de qual chamada de API é usada, outros locais são procurados antes/depois do caminho.

@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%)

Veja set /? para ajuda.

6
user6017774

Nenhum dos portos Win32 do Unix que eu encontrei na Internet é satistatico, porque todos eles têm uma ou mais dessas deficiências:

  • Não há suporte para a variável PATHEXT do Windows. (O que define a lista de extensões implicitamente adicionadas a cada comando antes de verificar o caminho e em qual ordem.) (Eu uso vários scripts tcl e não há publicamente disponível qual ferramenta poderia encontrá-los.)
  • Não há suporte para páginas de código cmd.exe, o que faz com que exibam caminhos com caracteres não-ascii incorretamente. (Sou muito sensível a isso, com o ç em meu primeiro nome :-))
  • Não há suporte para as regras de pesquisa distintas no cmd.exe e na linha de comando do PowerShell. (Nenhuma ferramenta disponível publicamente encontrará scripts .ps1 em uma janela do PowerShell, mas não em uma janela cmd!)

Então eu finalmente escrevi o meu próprio que, que suporta todos os itens acima corretamente.

Disponível lá: http://jf.larvoire.free.fr/progs/which.exe

6
Jean-François Larvoire

Eu estou usando GOW (GNU no Windows), que é uma versão light do Cygwin. Você pode pegar no GitHub aqui .

GOW (GNU no Windows) é a alternativa leve ao Cygwin. Ele usa um conveniente instalador do Windows que instala cerca de 130 aplicativos UNIX de código aberto extremamente úteis compilados como binários nativos do win32. Ele é projetado para ser o menor possível, cerca de 10 MB, ao contrário do Cygwin, que pode funcionar bem acima de 100 MB, dependendo das opções. - Sobre a Descrição (Brent R. Matzelle)

Uma captura de tela de uma lista de comandos incluídos no GOW:

 Enter image description here

6
Prayson W. Daniel

Eu criei ferramenta semelhante ao Ned Batchelder:

Procurando arquivos .dll e .exe no PATH

Enquanto minha ferramenta é primordialmente para a pesquisa de várias versões do dll, ela mostra mais informações (data, tamanho, versão), mas não usa o PATHEXT (espero atualizar minha ferramenta em breve).

5
Michał Niklas

Você pode primeiro instalar o Git deBaixando o Git, e então abrir o Git Bash e digitar:

which app-name
5
hamidreza samsami

Para seus usuários do Windows XP (que não possuem o comando where embutido), escrevi um comando "where like" como um rubygem chamado whichr.

Para instalá-lo, instale o Ruby.

Então

gem install whichr

Execute como:

C:> whichr cmd_aqui

3
rogerdpack

TCC e TCC/LE da JPSoft são substitutos do CMD.EXE que adicionam funcionalidades significativas. Relevante à pergunta do OP, which é um comando interno para processadores de comando da família TCC.

3
David G

Eu usei o módulo which do npm por um bom tempo, e ele funciona muito bem: https://www.npmjs.com/package/which É uma ótima alternativa multi-plataforma.

Agora mudei para o which que vem com o Git. Basta adicionar ao seu caminho o caminho /usr/bin do Git, que geralmente está em C:\Program Files\Git\usr\bin\which.exe. O binário which estará em C:\Program Files\Git\usr\bin\which.exe. É mais rápido e também funciona como esperado.

2
Giovanni Bassi

tente isso

set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
1
FeZZo