Existe um equivalente de 'que' na linha de comando do Windows?
-
08-07-2019 - |
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.
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:
- Disponível para Windows XP.
- Disponível desde PowerShell 1.0.
-
gcm
é um apelido paraGet-Command
cmdlet . - Sem nenhum parâmetro, ele lista para baixo todos os comandos disponíveis oferecidos pelo shell host.
- Você pode criar um alias de costume com
Set-Alias which gcm
e usá-lo como:.(which git).Source
- docs oficiais: https://technet.microsoft.com/en-us /library/ee176842.aspx
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:
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%)