web-dev-qa-db-fra.com

Existe-t-il un équivalent de 'qui' sur la ligne de commande Windows?

Comme j’ai parfois des problèmes de chemin, où l’un de mes propres scripts cmd est caché (suivi) par un autre programme (plus tôt sur le chemin), je voudrais pouvoir trouver le chemin complet d’un programme sur la ligne de commande Windows, étant donné juste son nom.

Existe-t-il un équivalent de la commande UNIX "qui"?

Sous UNIX, which command imprime le chemin complet de la commande donnée pour rechercher et résoudre facilement ces problèmes d’observation.

2178
namin

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 which fait, bien qu’il corresponde à tous les types de fichiers, pas seulement. commandes exécutables. (Il ne correspond pas aux commandes Shell intégrées telles que cd.) Il acceptera même les caractères génériques. where nt* trouve tous les fichiers de votre %PATH% et du répertoire en cours dont le nom commence par nt.

Essayez where /? pour obtenir de l'aide.

Notez que Windows PowerShell définit where comme un alias pour la cmdlet Where-Object , donc si vous voulez where.exe, vous devez taper le nom complet au lieu d'omettre l'extension .exe.

2388

Alors que les versions ultérieures de Windows ont une commande where, 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 et il n'est pas limité à PATH puisque vous pouvez remplacer n'importe quelle variable d'environnement (dans le 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.

278
paxdiablo

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 personnalisées exécutables via $Env:PATHEXT, etc. PowerShell, définis pour le shell actuel (assez similaire à type -a foo de Bash), ce qui en fait un meilleur outil de lecture que where.exe, which.exe, etc. ne sont pas au courant de ces commandes PowerShell.

Trouver 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 non-Windows (python, Ruby, Perl, etc.), vous devez ajouter les extensions de fichier correspondant à ces exécutables à la variable d'environnement PATHEXT (par défaut à .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL) afin d'identifier les fichiers portant ces extensions dans la variable PATH comme exécutable. Comme Get-Command respecte également cette variable, elle peut être étendue à la liste des 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 which gcm (forme abrégée de set-alias which get-command).

Vous trouverez plus d'informations et des exemples dans l'aide en ligne de Get-Command .

133
shalomb

Dans Windows PowerShell:

set-alias which where.exe
57
cmcginty

Si vous avez installé PowerShell (ce que je recommande), vous pouvez utiliser la commande suivante comme équivalent (remplacez programName par le nom de votre exécutable):

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

Plus est ici: Mon Manwich! PowerShell qui

38
RexE

Les outils GnuWin32 ont which, ainsi que de nombreux autres outils Unix.

36
Ferruccio

Dans Windows CMD which appelle where:

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

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 commande Windows Shell ou utiliser un shell * nix de votre choix). Il vous donne toute une foule de commandes * nix (telles que which) pour Windows, et vous pouvez simplement inclure ce répertoire dans votre PATH.

17
palswim

Dans PowerShell, il s'agit de gcm, qui fournit des informations formatées sur les autres commandes. Si vous voulez 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 de Get-Command cmdlet .
  • Sans aucun paramètre, il répertorie toutes les commandes disponibles proposées par l'hôte shell.
  • Vous pouvez créer un alias personnalisé avec Set-Alias which gcm et l'utiliser comme: (which git).Source.
  • Documents officiels: https://technet.Microsoft.com/en-us/library/ee176842.aspx
12
vulcan raven

Allez chercher unxutils d'ici: http://sourceforge.net/projects/unxutils/

or sur les plates-formes Windows, place tous les utilitaires Nice Unix sur un DOS standard. L'utilise depuis des années.

Il a un "qui" inclus. Notez que c'est sensible à la casse cependant.

NB: pour l’installer, exploser le fichier Zip quelque part et ajouter ...\UnxUtils\usr\local\wbin\à la variable env du chemin de votre système.

10
Jon Court

J'ai une fonction dans mon profil PowerShell nommée 'which'

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

Voici à quoi ressemble la sortie:

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

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.
8
Mawg

Pas en stock Windows mais il est fourni par Services for Unix et il existe plusieurs scripts de traitement par lots flottants qui accomplissent la même chose telle que celle-ci celle-ci .

7
Robert Gamble

La meilleure version de ceci que j'ai trouvée sur Windows est l'utilitaire "Whereis" de Joseph Newcomer, qui est disponible (avec source) à partir de son site .

L'article sur le développement de "Whereis" mérite d'être lu.

7
Tim Lesher

Ce fichier de commandes utilise la gestion des variables CMD pour rechercher la commande à exécuter dans le chemin. Remarque: le répertoire en cours 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.

6
user6017774

Aucun des ports Win32 de Unix que je n'ai pu trouver sur Internet n'est satistactif, 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.)
  • Aucune prise en charge des pages de code cmd.exe, ce qui leur permet d'afficher des chemins comportant des caractères non ascii de manière incorrecte. (Je suis très sensible à ça, 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 finalement écrit le mien, qui confirme tout ce qui précède correctement.

Disponible ici: http://jf.larvoire.free.fr/progs/which.exe

6

Vous pouvez d’abord installer Git à partir de Téléchargement de Git, puis ouvrez Git Bash et tapez:

which app-name
6
hamidreza samsami

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 programme d'installation Windows pratique qui installe environ 130 applications UNIX open source extrêmement utiles, compilées sous forme de fichiers binaires Win32 natifs. Il est conçu pour être aussi petit que possible, environ 10 Mo, contrairement à Cygwin, qui peut gérer bien plus de 100 Mo en fonction des options. - À propos de Description (Brent R. Matzelle)

Une capture d'écran d'une liste de commandes incluses dans GOW:

Enter image description here

6
Prayson W. Daniel

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 de 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).

5
Michał Niklas

Pour vous, utilisateurs de Windows XP (qui n’avez pas de commande where intégrée), j’ai écrit une commande "where like" sous la forme d’un rubygem appelé whichr.

Pour l'installer, installez Ruby.

Ensuite

gem install whichr

Courez comme ça:

C:> quel cmd_here

4
rogerdpack

TCC et TCC/LE de JPSoft sont des remplacements CMD.EXE qui ajoutent des fonctionnalités importantes. En rapport avec la question du PO, which est une commande intégrée destinée aux processeurs de commande de la famille TCC.

3
David G

J'ai utilisé le module which de npm pendant un bon bout de temps et cela fonctionne très bien: https://www.npmjs.com/package/which C'est une excellente alternative multi-plateformes .

Maintenant, je suis passé à la which fournie avec Git. Il suffit d’ajouter à 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 à C:\Program Files\Git\usr\bin\which.exe. C'est plus rapide et fonctionne également comme prévu.

2
Giovanni Bassi

essaye ça

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