risposta-alla-domanda-sullo-sviluppo-web-bd.com

Esiste un equivalente di "which" sulla riga di comando di Windows?

Poiché a volte ho problemi di percorso, in cui uno dei miei script cmd è nascosto (ombreggiato) da un altro programma (in precedenza sul percorso), mi piacerebbe essere in grado di trovare il percorso completo di un programma sulla riga di comando di Windows, dato solo il suo nome.

Esiste un equivalente al comando UNIX 'which'?

Su UNIX, which command stampa il percorso completo del comando dato per trovare e riparare facilmente questi problemi di shadowing.

2131
namin

Windows Server 2003 e versioni successive (ad esempio, dopo Windows XP 32 bit) fornisce il programma where.exe che esegue alcune delle funzioni di which, sebbene corrisponda a tutti i tipi di file, non solo ai comandi eseguibili. (Non corrisponde ai comandi Shell incorporati come cd.) Accetta anche i caratteri jolly, quindi where nt* trova tutti i file nel %PATH% e nella directory corrente i cui nomi iniziano con nt.

Prova where /? per aiuto.

Si noti che Windows PowerShell definisce where come alias per il cmdlet Where-Object , quindi se si desidera where.exe, è necessario digitare il nome completo invece di omettere il .exe estensione.

2338

Mentre le versioni successive di Windows hanno un comando where, puoi farlo anche con Windows XP usando i modificatori di variabile di ambiente, come segue:

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

Non hai bisogno di strumenti extra e non è limitato a PATH poiché puoi sostituire qualsiasi variabile d'ambiente (nel formato del percorso, ovviamente) che desideri utilizzare.


E, se ne vuoi uno in grado di gestire tutte le estensioni in PATHEXT (come fa Windows stesso), questo fa il trucco:

@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

In realtà restituisce tutte le possibilità, ma puoi modificarlo abbastanza facilmente per specifiche regole di ricerca.

275
paxdiablo

Sotto PowerShell, Get-Command troverà gli eseguibili ovunque 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

Trova anche cmdlet, funzioni, alias, file con estensioni dei file eseguibili personalizzati tramite $Env:PATHEXT, ecc. Definiti per la shell corrente (molto simile a type -a foo di Bash) - rendendolo un metodo migliore di altri strumenti come where.exe, which.exe, ecc. non sono a conoscenza di questi comandi di PowerShell.

Trovare gli eseguibili usando solo parte del 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
...

Ricerca di eseguibili personalizzati

Per trovare altri eseguibili non di windows (python, Ruby, Perl, ecc.), Le estensioni di file per questi eseguibili devono essere aggiunte alla variabile ambientale PATHEXT (di default a .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL) per identificare i file con queste estensioni in PATH come eseguibile. Poiché Get-Command onora anche questa variabile, può essere estesa per elencare i file eseguibili personalizzati. per esempio.

$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

È possibile impostare rapidamente un alias con sal which gcm (forma abbreviata di set-alias which get-command).

Ulteriori informazioni ed esempi possono essere trovati nella guida in linea per Get-Command .

130
shalomb

In Windows PowerShell:

set-alias which where.exe
54
cmcginty

Se hai installato PowerShell (che consiglio), puoi utilizzare il seguente comando come equivalente approssimativo (sostituisci nomeprogramma per il nome del tuo eseguibile):

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

Più è qui: My Manwich! PowerShell Quale

38
RexE

Gli strumenti di GnuWin32 hanno which, insieme a un gran numero di altri strumenti Unix.

34
Ferruccio

In Windows CMD which chiama where:

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

Cygwin è una soluzione. Se non ti dispiace usare una soluzione di terze parti, allora Cygwin è la strada da percorrere.

Cygwin ti dà il comfort di * nix nell'ambiente Windows (e puoi usarlo nel tuo comando Shell di Windows o usare una shell * nix a tua scelta). Ti dà un intero host di comandi * nix (come which) per Windows, e puoi semplicemente includere quella directory nel tuo PATH.

17
palswim

In PowerShell, è gcm, che fornisce informazioni formattate su altri comandi. Se si desidera recuperare solo il percorso dell'eseguibile, utilizzare .Source.

Ad esempio: gcm git o (gcm git).Source

Tidbits:

12
vulcan raven

Ho una funzione nel mio profilo PowerShell chiamato 'which'

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

Ecco come appare l'output:

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

Vai a prendere unxutils da qui: http://sourceforge.net/projects/unxutils/

oro su piattaforme Windows, mette tutte le utility Nice unix su un DOS Windows standard. Lo stavo usando da anni.

Ha un "che" incluso. Si noti che è maiuscole/minuscole.

NB: per installarlo fai esplodere lo Zip da qualche parte e aggiungi ...\UnxUtils\usr\local\wbin\alla variabile env del tuo percorso di sistema.

9
Jon Court

Se riesci a trovare un compilatore Pascal gratuito, puoi compilarlo. Almeno funziona e mostra l'algoritmo necessario.

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

Windows non è disponibile ma è fornito da Services for Unix e ci sono diversi semplici script batch che girano attorno alla stessa cosa questo .

7
Robert Gamble

La versione migliore di ciò che ho trovato su Windows è l'utilità "whereis" di Joseph Newcomer, che è disponibile (con origine) da il suo sito .

Vale la pena leggere l'articolo sullo sviluppo di "whereis".

7
Tim Lesher

Questo file batch utilizza la gestione delle variabili CMD per trovare il comando che verrebbe eseguito nel percorso. Nota: la directory corrente viene sempre eseguita prima del percorso) e, a seconda della chiamata API utilizzata, vengono cercati altri percorsi prima/dopo il percorso.

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

Vedi set /? per aiuto.

6
user6017774

Nessuna delle porte Win32 di Unix che potrei trovare su Internet è soddisfacente, perché tutte hanno una o più di queste carenze:

  • Nessun supporto per la variabile PATHEXT di Windows. (Che definisce l'elenco di estensioni implicitamente aggiunte a ciascun comando prima di analizzare il percorso e in quale ordine.) (Uso molti script tcl e non è disponibile pubblicamente quale strumento potrebbe trovarli.)
  • Nessun supporto per le code page cmd.exe, che consente di visualizzare i percorsi con caratteri non ascii in modo errato. (Sono molto sensibile a questo, con il ç nel mio nome :-))
  • Nessun supporto per le distinte regole di ricerca in cmd.exe e nella riga di comando di PowerShell. (Nessuno strumento pubblicamente disponibile troverà script .ps1 in una finestra di PowerShell, ma non in una finestra di cmd!)

Così alla fine ho scritto il mio che, che sostiene correttamente tutto quanto sopra.

Disponibile lì: http://jf.larvoire.free.fr/progs/which.exe

Puoi prima installare Git da Download di Git, quindi aprire Git Bash e digitare:

which app-name
6

Sto usando GOW (GNU su Windows) che è una versione leggera di Cygwin. Puoi prenderlo da GitHub qui .

GOW (GNU su Windows) è l'alternativa leggera a Cygwin. Usa un comodo programma di installazione di Windows che installa circa 130 applicazioni UNIX open source estremamente utili compilate come binari nativi di win32. È progettato per essere il più piccolo possibile, circa 10 MB, rispetto a Cygwin che può funzionare ben oltre i 100 MB a seconda delle opzioni. - Informazioni sulla descrizione (Brent R. Matzelle)

Uno screenshot di un elenco di comandi inclusi in GOW:

Enter image description here

6

Ho creato uno strumento simile a Ned Batchelder:

Ricerca di file .dll e .exe in PATH

Mentre il mio strumento è principalmente per la ricerca di varie versioni di dll mostra maggiori informazioni (data, dimensione, versione) ma non usa PATHEXT (spero di aggiornare presto il mio strumento).

5
Michał Niklas

Per voi utenti di Windows XP (che non hanno il comando where integrato), ho scritto un comando "where like" come un rubygem chiamato whichr.

Per installarlo, installa Ruby.

Poi

gem install whichr

Eseguilo come:

C:> whor cmd_qui

4
rogerdpack

TCC e TCC/LE di JPSoft sono sostituzioni CMD.EXE che aggiungono funzionalità significative. Per quanto riguarda la domanda dell'OP, which è un comando incorporato per i processori di comandi della famiglia TCC.

3
David G

Ho usato il modulo which da npm per un po 'di tempo, e funziona molto bene: https://www.npmjs.com/package/which È una grande alternativa multi piattaforma.

Ora sono passato a which che viene fornito con Git. Basta aggiungere al percorso il percorso /usr/bin da Git, che di solito è C:\Program Files\Git\usr\bin\which.exe. Il binario which sarà C:\Program Files\Git\usr\bin\which.exe. È più veloce e funziona come previsto.

2
Giovanni Bassi

prova questo

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