Pergunta

Como eu às vezes têm problemas de caminho, onde um dos meus próprios scripts cmd está escondido (sombreado) por outro programa (mais cedo no caminho), eu gostaria de ser capaz de encontrar o caminho completo para um programa no comando do Windows linha, dada apenas o seu nome.

Existe um equivalente ao comando UNIX 'que'?

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

Foi útil?

Solução

Windows Server 2003 e posterior (ou seja, qualquer coisa depois do Windows XP 32 bits) fornecer o programa where.exe que faz parte do que which faz, embora corresponda a todos os tipos de arquivos, não apenas comandos executáveis. (Ele não coincide com built-in comandos shell como cd.) Ele vai mesmo aceitar curingas, por isso where nt* encontra todos os arquivos em seu %PATH% e diretório atual cujos nomes começam com nt.

Tente where /? para obter ajuda.

Note que o Windows PowerShell define where como um alias para o Where-Object cmdlet , então se você quiser where.exe, você precisa digitar o nome completo em vez de omitir a extensão .exe.

Outras dicas

Enquanto as versões mais recentes do Windows tem um comando where, você também pode fazer isso com o Windows XP usando os modificadores ambiente variáveis, como a seguir:

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 ferramentas extras e não é limitado a PATH desde que você pode substituir qualquer variável de ambiente (no formato de caminho, é claro) que você deseja usar.


E, se você quer um que pode 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

Na verdade, retorna todas as possibilidades, mas você pode ajustá-lo com bastante facilidade para as regras de pesquisa específicos.

De acordo com PowerShell, Get-Command vai encontrar executáveis ??em qualquer lugar $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 PowerShell, funções, aliases, arquivos com executáveis ??personalizados extensões via $Env:PATHEXT, etc. definido para o shell atual (bastante semelhante ao type -a foo do Bash) - tornando-se uma melhor go to-do que outras ferramentas como where.exe, which.exe , etc, que não têm conhecimento destes comandos PowerShell.

Encontrar 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
...

Finding costume executáveis ??

Para encontrar outros executáveis ??não-Windows (Python, Ruby, Perl, etc), extensões de arquivo para os executáveis ??precisam ser adicionados à variável ambiental PATHEXT (padrão para .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL) para identificar arquivos com essas extensões no PATH como executável . Como Get-Command também homenageia esta variável, ele pode ser estendido para executáveis ??lista personalizada. 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 sob a ajuda online para Get-Command .

No Windows PowerShell:

set-alias which where.exe

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

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

Mais é aqui: Meu Manwich! PowerShell Qual

O GnuWin32 ferramentas têm which, juntamente com toda uma série de outras ferramentas Unix.

No Windows CMD which chama where:

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

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

Cygwin lhe dá o conforto de * nix no ambiente Windows (e você pode usá-lo em sua shell de comando do Windows, ou usar um shell * nix de sua escolha). Dá-lhe toda uma série de comandos * nix (como which) para Windows, e você só pode incluir esse diretório em sua PATH.

Em PowerShell, é gcm, que dá informação formatada sobre outros comandos. Se você deseja recuperar único caminho para o executável, .Source uso.

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

Tidbits:

Go obter UnxUtils daqui: http://sourceforge.net/projects/unxutils/

ouro em plataformas Windows, coloca todos os bons utilitários Unix no Windows padrão DOS. Foi usado por anos.

Tem um 'que' incluído. Note que é que diferencia maiúsculas de minúsculas.

NB: para instalá-lo explodir a algum lugar zip e adicione ... \ UnxUtils \ usr \ Local \ wbin \ ao seu sistema variável env caminho

.

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

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

Aqui está o que os olhares de saída como:

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:

Se você puder encontrar um compilador Pascal gratuito, você pode compilar este. Pelo menos ele 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.

Não está em estoque Windows, mas ele é fornecido por Services for Unix e há vários scripts simples em lote por aí que realizar a mesma coisa este este .

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

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

Nenhum dos portos Win32 de Unix que que eu poderia encontrar na Internet são satistactory, porque todos eles têm uma ou mais destas deficiências:

  • Não há suporte para Windows PATHEXT variável. (Que define a lista de extensões implicitely adicionados a cada comando antes de digitalizar o caminho, e em que ordem.) (Eu uso um monte de TCL scripts e não disponíveis publicamente qual ferramenta poderia encontrá-los.)
  • Não há suporte para páginas de código cmd.exe, o que os torna exibir caminhos com caracteres não-ascii incorretamente. (Eu sou muito sensível a isso, com o C no meu primeiro nome: -))
  • Não há suporte para as regras de pesquisa distintas em cmd.exe e da linha de comando PowerShell. (Sem publicamente ferramenta disponível vai encontrar .ps1 scripts em uma janela do PowerShell, mas não em uma janela cmd!)

Então, eu finalmente escrevi o meu próprio que, que suports todo o exposto corretamente.

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

Este arquivo de lote usa manipulação variável CMD para encontrar o comando que seria executado no caminho. Nota:. Que o diretório atual é sempre feito antes do caminho) e, dependendo da chamada de API é usado em outros locais são pesquisados ??antes / depois o 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 obter ajuda.

Você pode instalar primeiro o Git de Downloading Git , e em seguida, abra Git Bash e digite:

which app-name

Eu estou usando GOW (GNU no Windows), que é uma versão light do Cygwin. Você pode agarrá-lo a partir GitHub aqui .

GOW (GNU no Windows) é a alternativa leve para Cygwin. ele usa um instalador conveniente Windows que instala cerca de 130 extremamente aplicações UNIX de código aberto úteis compilados como win32 nativo binários. Ele é projetado para ser tão pequena quanto possível, cerca de 10 MB, como oposição ao Cygwin que pode executar mais de 100 MB, dependendo opções. - Sobre Descrição (Brent R. Matzelle)

Um screenshot de uma lista de comandos incluídos no GOW:

Digite os detalhes da imagem aqui

Eu tenho uma ferramenta similar para Ned Batchelder criado:

Pesquisando arquivos .dll e .exe no PATH

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

Para você os usuários do Windows XP (que não têm nenhum comando where built-in), eu escrevi um "onde como" comando como um rubygem chamado whichr.

Para instalá-lo, instalar o Ruby.

Em seguida

gem install whichr

Execute-o como:

C:> whichr cmd_here

TCC e TCC / LE a partir JPSoft são substitutos CMD.EXE que adicionam funcionalidade significativa. Relevantes para a pergunta do OP, which é um comando builtin para processadores de comando da família de CTP.

Eu tenho usado o módulo which de NPM por um bom tempo, e ele funciona muito bem: https: //www.npmjs.com/package/which É uma grande múltiplas plataforma alternativa.

Agora eu mudei para o which que vem com o Git. Basta adicionar ao seu caminho o caminho /usr/bin do Git, que geralmente é a 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.

Tente este

set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top