the - windows variables path




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

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.


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

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


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


Esse arquivo em lote usa o tratamento de variáveis ​​CMD para localizar o comando que seria executado no caminho. Nota: que 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 o set /? para ajuda.


Eu criei ferramenta semelhante ao Ned Batchelder:

Procurando arquivos .dll e .exe no PATH

Enquanto minha ferramenta é primordialmente para procurar de várias versões de dll mostra mais informação (data, tamanho, versão) mas não usa PATHEXT (eu espero atualizar minha ferramenta logo).


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:

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

Agora eu mudei para o 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 which binário estará em C:\Program Files\Git\usr\bin\which.exe . É mais rápido e também funciona como esperado.


Não sei se isso ajuda. Postado como resposta porque não sei como formatar código nos comentários (ajuda?)

Se você puder encontrar um compilador pascal gratuito, você pode compilar isso, ou mandar um e-mail para mim e eu posso tentar cavar um, ou mandar um e-mail para o exe ou postá-lo em algum lugar. Eu posto o código, por pior que seja, porque 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 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.

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

  • Não há suporte para a variável Windows PATHEXT. (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


No Windows CMD, which chama where :

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

No windows powershell:

set-alias which where.exe

Para você usuários do XP (que não possuem nenhum comando embutido), eu escrevi um comando "where like" como um rubygem chamado whichr

Para instalá-lo, instale o ruby

então

gem install whichr

corra como

c:\>whichr cmd_here



Surpreso que ninguém tenha mencionado o cygwin como uma solução ainda. 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 shell de comando do Windows ou usar um shell * nix de sua escolha). Ele oferece uma grande quantidade de comandos * nix (como o) para o Windows, e você pode simplesmente incluir esse diretório em seu PATH .


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






path-variables