it-swarm.com.de

Gibt es ein Äquivalent von "which" in der Windows-Befehlszeile?

Da ich manchmal Pfadprobleme habe, bei denen eines meiner eigenen Cmd-Skripte von einem anderen Programm (früher auf dem Pfad) verborgen (beschattet) wird, möchte ich in der Lage sein, den vollständigen Pfad zu einem angegebenen Programm auf der Windows-Befehlszeile zu finden nur sein Name.

Gibt es ein Äquivalent zum UNIX-Befehl 'which'?

Unter UNIX gibt which command den vollständigen Pfad des angegebenen Befehls aus, um diese Schattenprobleme leicht zu finden und zu beheben.

2178
namin

Windows Server 2003 und höher (d. H. Alles nach Windows XP 32 Bit) stellen das Programm where.exe bereit, das einen Teil der Funktionen von which ausführt, obwohl es mit allen Dateitypen und nicht nur mit ausführbaren Befehlen übereinstimmt. (Es stimmt nicht mit integrierten Shell-Befehlen wie cd überein.) Es akzeptiert sogar Platzhalter, sodass where nt* alle Dateien in Ihrem %PATH% und dem aktuellen Verzeichnis findet, deren Namen mit nt beginnen.

Versuchen Sie es mit where /?, um Hilfe zu erhalten.

Beachten Sie, dass Windows PowerShell where als Alias ​​für das Cmdlet Where-Object definiert. Wenn Sie also where.exe möchten, müssen Sie den vollständigen Namen eingeben, anstatt die Erweiterung .exe wegzulassen.

2388

Während spätere Windows-Versionen den Befehl where haben, können Sie dies auch mit Windows XP tun, indem Sie die Umgebungsvariablen-Modifikatoren wie folgt verwenden:

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

Sie benötigen keine zusätzlichen Tools und sind nicht auf PATH beschränkt, da Sie jede Umgebungsvariable (natürlich im Pfadformat) ersetzen können, die Sie verwenden möchten.


Und wenn Sie eine möchten, die alle Erweiterungen in PATHEXT unterstützt (wie Windows selbst), ist dies der Trick:

@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

Eigentlich gibt es alle Möglichkeiten zurück, aber Sie können es ganz einfach für bestimmte Suchregeln anpassen.

278
paxdiablo

Unter PowerShell findet Get-Command ausführbare Dateien überall in _$Env:PATH_.

_Get-Command eventvwr

CommandType   Name          Definition
-----------   ----          ----------
Application   eventvwr.exe  c:\windows\system32\eventvwr.exe
Application   eventvwr.msc  c:\windows\system32\eventvwr.msc
_

Außerdem werden PowerShell-Cmdlets, -Funktionen, -Aliasnamen, -Dateien mit benutzerdefinierten Erweiterungen für ausführbare Dateien über _$Env:PATHEXT_ usw. gefunden, die für die aktuelle Shell definiert sind (vergleichbar mit Bashs _type -a foo_) Tools wie _where.exe_, _which.exe_ usw., die diese PowerShell-Befehle nicht kennen.

Suchen von ausführbaren Dateien mit nur einem Teil des Namens

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

Benutzerdefinierte ausführbare Dateien suchen

Um andere ausführbare Dateien zu finden (Python, Ruby, Perl usw.), müssen der Umgebungsvariablen PATHEXT Dateierweiterungen für diese ausführbaren Dateien hinzugefügt werden (standardmäßig _.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL_), um Dateien mit diesen Erweiterungen zu identifizieren in der PATH als ausführbar. Da _Get-Command_ auch diese Variable berücksichtigt, kann sie erweitert werden, um benutzerdefinierte ausführbare Dateien aufzulisten. z.B.

_$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
_

Mit _sal which gcm_ (Kurzform von _set-alias which get-command_) können Sie schnell einen Alias ​​erstellen.

Weitere Informationen und Beispiele finden Sie in der Online-Hilfe zu Get-Command .

133
shalomb

In Windows PowerShell:

set-alias which where.exe
57
cmcginty

Wenn Sie PowerShell installiert haben (was ich empfehle), können Sie den folgenden Befehl als grobe Entsprechung verwenden (ersetzen Sie programName für den Namen Ihrer ausführbaren Datei):

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

Mehr ist hier: My Manwich! PowerShell Which

38
RexE

Die GnuWin32 Tools haben which, zusammen mit einer ganzen Reihe anderer Unix-Tools.

36
Ferruccio

In Windows CMD ruft whichwhere auf:

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

Cygwin ist eine Lösung. Wenn es Ihnen nichts ausmacht, eine Drittanbieterlösung zu verwenden, ist Cygwin der richtige Weg.

Cygwin bietet Ihnen den Komfort von * nix in der Windows-Umgebung (und Sie können es in Ihrer Windows-Befehls-Shell oder einer * nix-Shell Ihrer Wahl verwenden). Es gibt Ihnen eine ganze Reihe von * nix-Befehlen (wie which) für Windows, und Sie können dieses Verzeichnis einfach in Ihr PATH aufnehmen.

17
palswim

In PowerShell ist es gcm, das formatierte Informationen zu anderen Befehlen enthält. Wenn Sie nur den Pfad zur ausführbaren Datei abrufen möchten, verwenden Sie .Source.

Zum Beispiel: gcm git oder (gcm git).Source

Leckerbissen:

  • Verfügbar für Windows XP.
  • Verfügbar seit PowerShell 1.0.
  • gcm ist ein Alias ​​von Get-Command Cmdlet .
  • Ohne Parameter werden alle verfügbaren Befehle aufgelistet, die von der Host-Shell angeboten werden.
  • Sie können mit Set-Alias which gcm einen benutzerdefinierten Alias ​​erstellen und wie folgt verwenden: (which git).Source.
  • Offizielle Dokumente: https://technet.Microsoft.com/en-us/library/ee176842.aspx
12
vulcan raven

Holen Sie sich Unxutils von hier: http://sourceforge.net/projects/unxutils/

gold auf Windows-Plattformen, setzt alle Nizza Unix-Dienstprogramme auf einem Standard-Windows-DOS. Ich benutze es seit Jahren.

Es hat ein "Was" enthalten. Beachten Sie jedoch, dass zwischen Groß- und Kleinschreibung unterschieden wird.

NB: um es zu installieren, explodieren Sie die Zip-Datei und fügen Sie ...\UnxUtils\usr\local\wbin\zu Ihrer Systempfad-Umgebungsvariablen hinzu.

10
Jon Court

Ich habe eine Funktion in meinem PowerShell-Profil mit dem Namen "which".

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

So sieht die Ausgabe aus:

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

Wenn Sie einen freien Pascal-Compiler finden, können Sie diesen kompilieren. Zumindest funktioniert es und zeigt den notwendigen Algorithmus.

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

Nicht auf Lager Windows, aber es wird von Services for Unix bereitgestellt, und es gibt mehrere einfache Batch-Skripte, die das Gleiche bewirken, wie dies dieses .

7
Robert Gamble

Die beste Version davon, die ich unter Windows gefunden habe, ist Joseph Newcomers "whereis" -Dienstprogramm, das (mit Quelle) von seiner Site verfügbar ist.

Der Artikel über die Entwicklung von "whereis" ist lesenswert.

7
Tim Lesher

Diese Batchdatei verwendet die CMD-Variablenbehandlung, um den Befehl zu finden, der im Pfad ausgeführt werden würde. Hinweis: Das aktuelle Verzeichnis wird immer vor dem Pfad erstellt. Abhängig davon, welcher API-Aufruf verwendet wird, werden andere Speicherorte vor/nach dem Pfad durchsucht.

@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%)

Siehe set /? für Hilfe.

6
user6017774

Keiner der Win32-Ports von Unix, die ich im Internet finden konnte, ist zufriedenstellend, da alle einen oder mehrere der folgenden Mängel aufweisen:

  • Keine Unterstützung für die Windows-Variable PATHEXT. (Dies definiert die Liste der Erweiterungen, die vor dem Scannen des Pfads implizit zu jedem Befehl hinzugefügt wurden, und in welcher Reihenfolge.)
  • Keine Unterstützung für cmd.exe-Codeseiten, wodurch Pfade mit Nicht-ASCII-Zeichen falsch angezeigt werden. (Ich bin sehr empfindlich, mit dem ç in meinem Vornamen :-))
  • Keine Unterstützung für die unterschiedlichen Suchregeln in cmd.exe und der PowerShell-Befehlszeile. (Kein öffentlich verfügbares Tool findet .ps1-Skripte in einem PowerShell-Fenster, jedoch nicht in einem cmd-Fenster!)

Also habe ich irgendwann meine eigene geschrieben, die all das richtig unterstützt.

Verfügbar dort: http://jf.larvoire.free.fr/progs/which.exe

Sie können Git zuerst von Herunterladen von Git installieren, dann Git Bash öffnen und Folgendes eingeben:

which app-name
6

Ich benutze GOW (GNU unter Windows), eine Light-Version von Cygwin. Sie können es von GitHub holen hier .

GOW (GNU unter Windows) ist die leichtgewichtige Alternative zu Cygwin. Es verwendet ein praktisches Windows-Installationsprogramm, mit dem ungefähr 130 äußerst nützliche Open-Source-UNIX-Anwendungen installiert werden, die als native Win32-Binärdateien kompiliert wurden. Es soll so klein wie möglich sein, etwa 10 MB, im Gegensatz zu Cygwin, das je nach Option weit über 100 MB ausführen kann. - Über Beschreibung (Brent R. Matzelle)

Ein Screenshot einer Liste der in GOW enthaltenen Befehle:

Enter image description here

6

Ich habe ein ähnliches Tool wie Ned Batchelder erstellt:

Durchsuchen von DLL- und EXE-Dateien in PATH

Während mein Tool hauptsächlich für die Suche nach verschiedenen DLL-Versionen vorgesehen ist, werden mehr Informationen (Datum, Größe, Version) angezeigt, aber PATHEXT wird nicht verwendet (ich hoffe, mein Tool bald zu aktualisieren).

5
Michał Niklas

Für Sie Windows XP-Benutzer (die keinen eingebauten where -Befehl haben) habe ich einen "where like" -Befehl als Rubygem namens whichr geschrieben.

Installieren Sie Ruby, um es zu installieren.

Dann

gem install whichr

Führen Sie es wie folgt aus:

C:> whichr cmd_here

4
rogerdpack

TCC und TCC/LE von JPSoft sind CMD.EXE-Ersetzungen, die wichtige Funktionen hinzufügen. In Bezug auf die Frage des OP ist which ein integrierter Befehl für Befehlsprozessoren der TCC-Familie.

3
David G

Ich habe das which -Modul von npm eine ganze Weile benutzt und es funktioniert sehr gut: https://www.npmjs.com/package/which Es ist eine großartige plattformübergreifende Alternative .

Jetzt bin ich auf das which umgestiegen, das mit Git geliefert wird. Fügen Sie Ihrem Pfad einfach den Pfad /usr/bin von Git hinzu, der sich normalerweise bei C:\Program Files\Git\usr\bin\which.exe befindet. Die Binärdatei which befindet sich bei C:\Program Files\Git\usr\bin\which.exe. Es ist schneller und funktioniert auch wie erwartet.

2
Giovanni Bassi

versuche dies

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