Existe-t-il un équivalent de 'qui' sur la ligne de commande Windows?
-
08-07-2019 - |
Question
Comme j'ai parfois des problèmes de chemin, lorsqu'un de mes propres scripts cmd est masqué (suivi) par un autre programme (plus tôt sur le chemin), j'aimerais pouvoir trouver le chemin complet d'un programme à l'aide de la commande Windows. ligne, juste son nom.
Existe-t-il un équivalent de la commande UNIX "which"?
Sous UNIX, quelle commande
imprime le chemin complet de la commande donnée pour rechercher et réparer facilement ces problèmes d'observation.
La solution
Windows Server 2003 et versions ultérieures (c’est-à-dire après Windows XP 32 bits) fournissent le programme where.exe
qui effectue une partie de ce que que
fait, bien qu'il corresponde à tous les types des fichiers, pas seulement des commandes exécutables. (Il ne correspond pas aux commandes de shell intégrées telles que cd
.) Il acceptera même les caractères génériques. où nt *
trouve tous les fichiers de votre % PATH%
et le répertoire en cours dont les noms commencent par nt
.
Essayez d’aider où /?
.
Notez que Windows PowerShell définit où
est un alias pour la cmdlet Where-Object
, donc si vous voulez where.exe
, vous devez taper le nom complet au lieu d'omettre le .exe
extension.
Autres conseils
Alors que les versions ultérieures de Windows ont une commande où
, vous pouvez également le faire avec Windows XP en utilisant les modificateurs de variable d'environnement, comme suit:
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
Vous n'avez besoin d'aucun outil supplémentaire ni de CHEMIN
, car vous pouvez remplacer n'importe quelle variable d'environnement (au format du chemin, bien sûr) que vous souhaitez utiliser.
Et si vous en voulez un qui puisse gérer toutes les extensions de PATHEXT (comme Windows le fait lui-même), celui-ci fait l'affaire:
@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
Il renvoie en fait toutes les possibilités, mais vous pouvez le modifier assez facilement pour des règles de recherche spécifiques.
Sous PowerShell, Get-Command
trouvera les fichiers exécutables n’importe où dans $ Env: PATH
.
Get-Command eventvwr
CommandType Name Definition
----------- ---- ----------
Application eventvwr.exe c:\windows\system32\eventvwr.exe
Application eventvwr.msc c:\windows\system32\eventvwr.msc
Il trouve également des applets de commande, des fonctions, des alias, des fichiers avec des extensions personnalisables personnalisées PowerShell via $ Env: PATHEXT
, etc. définis pour le shell actuel (assez semblable au type de Bash - a foo
) - un meilleur choix que d'autres outils tels que where.exe
, which.exe
, etc., qui ne connaissent pas ces commandes PowerShell.
Recherche des exécutables en utilisant seulement une partie du nom
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
...
Recherche d'exécutables personnalisés
Pour rechercher d'autres exécutables autres que Windows (python, ruby, perl, etc.), vous devez ajouter les extensions de fichier correspondant à ces exécutables à la variable d'environnement PATHEXT
(la valeur par défaut est .COM; .EXE; .BAT; .CMD; .VBS; .VBE; .JS; .JSE; .WSF; .WSH; .MSC; .CPL
) pour identifier les fichiers avec ces extensions dans le PATH
comme exécutable. Comme Get-Command
respecte également cette variable, elle peut être étendue pour répertorier les exécutables personnalisés. par exemple
$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
Vous pouvez rapidement créer un alias avec sal qui gcm
(forme abrégée de alias-set qui obtient la commande
).
Vous trouverez plus d'informations et des exemples dans l'aide en ligne de Get-Command
.
Dans Windows PowerShell:
set-alias which where.exe
Si vous avez PowerShell installé (ce que je recommande), vous pouvez utiliser la commande suivante comme équivalent (substituez programName au nom de votre exécutable):
($Env:Path).Split(";") | Get-ChildItem -filter programName*
Plus est ici: Mon Manwich! PowerShell qui
outils GnuWin32 ont qui
, ainsi qu'un grand nombre d'autres Unix outils.
Dans Windows CMD que
appelle où
:
$ where php
C:\Program Files\PHP\php.exe
Cygwin est une solution. Si cela ne vous dérange pas d’utiliser une solution tierce, Cygwin est la solution.
Cygwin vous offre le confort de * nix dans l’environnement Windows (et vous pouvez l’utiliser dans votre shell de commande Windows ou utiliser un shell * nix de votre choix). Il vous donne toute une série de commandes * nix (telles que which
) pour Windows, et vous pouvez simplement inclure ce répertoire dans votre CHEMIN
.
Dans PowerShell, il s'agit de gcm
, qui fournit des informations formatées sur les autres commandes. Si vous souhaitez récupérer uniquement le chemin d'accès à l'exécutable, utilisez .Source
.
Par exemple: gcm git
ou (gcm git) .Source
Tidbits:
- Disponible pour Windows XP.
- Disponible depuis PowerShell 1.0.
-
gcm
est un alias deGet-Command
cmdlet . - Sans aucun paramètre, il répertorie toutes les commandes disponibles proposées par le shell de l'hôte.
- Vous pouvez créer un alias personnalisé avec
Set-Alias ??qui gcm
et l'utiliser comme suit:(quel git) .Source
. - Documents officiels: https://technet.microsoft.com/en-us /library/ee176842.aspx
Allez chercher unxutils à partir d'ici: http://sourceforge.net/projects/unxutils/
gold sur les plates-formes Windows, place tous les utilitaires Unix sur un DOS standard. Je l'utilise depuis des années.
Il a un 'qui' inclus. Notez qu'il est sensible à la casse cependant.
NB: pour l’installer, exploser le zip quelque part et ajouter ... \ UnxUtils \ usr \ local \ wbin \ à la variable env du chemin de votre système.
J'ai une fonction dans mon profil PowerShell nommée 'which'
function which {
get-command $args[0]| format-list
}
Voici à quoi ressemble le résultat:
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:
Si vous pouvez trouver un compilateur Pascal gratuit, vous pouvez le compiler. Au moins, cela fonctionne et montre l’algorithme nécessaire.
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.
Windows n'est pas en stock, mais fourni par Services pour Unix . et il existe plusieurs scripts de traitement par lots flottants qui accomplissent la même chose, par exemple celui-ci .
La meilleure version de ce que j'ai trouvé sous Windows est "Whereis" de Joseph Newcomer. Cet utilitaire est disponible (avec la source) à partir de son site .
L'article sur le développement de "whereis". mérite d'être lu.
Aucun des ports Win32 d’Unix que je pourrais trouver sur Internet n’est satisfaisant, car ils présentent tous un ou plusieurs de ces inconvénients:
- Pas de support pour la variable Windows PATHEXT. (Ce qui définit la liste des extensions ajoutées implicitement à chaque commande avant de scanner le chemin, et dans quel ordre.) (J'utilise beaucoup de scripts tcl, et aucun outil public ne peut les trouver.)
- Pas de prise en charge des pages de code cmd.exe, ce qui leur permet d'afficher des chemins comportant des caractères non ASCII correctement. (Je suis très sensible à cela, avec le ç dans mon prénom: -))
- Aucune prise en charge des règles de recherche distinctes dans cmd.exe et de la ligne de commande PowerShell. (Aucun outil accessible au public ne trouvera les scripts .ps1 dans une fenêtre PowerShell, mais pas dans une fenêtre cmd!)
J'ai donc fini par écrire le mien, qui confirme tout ce qui précède correctement.
Disponible ici: http://jf.larvoire.free.fr/progs/which.exe
Ce fichier de commandes utilise la gestion des variables CMD pour rechercher la commande à exécuter dans le chemin. Remarque: le répertoire actuel est toujours défini avant le chemin) et, en fonction de l'appel d'API utilisé, d'autres emplacements sont recherchés avant / après le chemin.
@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%)
Voir set /?
pour obtenir de l'aide.
Vous pouvez d’abord installer Git à partir de Télécharger Git , et puis ouvrez Git Bash et tapez:
which app-name
J'utilise GOW (GNU sous Windows), une version allégée de Cygwin. Vous pouvez le récupérer sur GitHub ici .
GOW (GNU sous Windows) est l’alternative légère à Cygwin. Il utilise un installateur Windows pratique qui installe environ 130 extrêmement applications UNIX open source utiles compilées en win32 natif binaires. Il est conçu pour être aussi petit que possible, environ 10 Mo, opposé à Cygwin, qui peut durer bien plus de 100 Mo en fonction de options. - Description de la description (Brent R. Matzelle)
Une capture d'écran d'une liste de commandes incluses dans GOW:
J'ai créé un outil similaire à Ned Batchelder:
Recherche de fichiers .dll et .exe dans PATH
Bien que mon outil soit principalement destiné à la recherche dans différentes versions de dll, il affiche plus d'informations (date, taille, version), mais il n'utilise pas PATHEXT (j'espère mettre à jour mon outil prochainement).
Pour vous, utilisateurs Windows & XP (qui ne possèdent pas de commande où
dans la commande intégrée), j'ai écrit un " where like " commande en tant que rubygem appelé whor
.
Pour l'installer, installez Ruby.
Alors
gem install whichr
Exécutez-le comme suit:
C: > quel cmd_here
TCC et TCC / LE de JPSoft sont des remplacements CMD.EXE qui ajoutent des fonctionnalités importantes. En rapport avec la question du PO, qui
est une commande intégrée destinée aux processeurs de commandes de la famille TCC.
J'ai utilisé le module
de npm pendant un bon bout de temps et il fonctionne très bien: https://www.npmjs.com/package/which
C’est une excellente alternative multi-plateformes.
Maintenant, je suis passé au
fourni avec Git. Ajoutez simplement à votre chemin le chemin / usr / bin
de Git, qui se trouve généralement à C: \ Program Files \ Git \ usr \ bin \ which.exe
. Le binaire which
sera situé dans C: \ Program Files \ Git \ usr \ bin \ which.exe
. Il est plus rapide et fonctionne également comme prévu.
essayez ceci
set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)