Jay Taylor's notes
back to listing indexIs there an equivalent of 'which' on the Windows command line? - Stack Overflow
[web search]- Home
-
- Public
- Stack Overflow
- Tags
- Users
- Jobs
-
-
Teams
-
Free 30 Day Trial
-
As I sometimes have path problems, where one of my own cmd scripts is hidden (shadowed) by another program (earlier on the path), I would like to be able to find the full path to a program on the Windows command line, given just its name.
Is there an equivalent to the UNIX command 'which'?
On UNIX, which command
prints the full path of the given command to easily find and repair these shadowing problems.
which
command in standard Unix. The POSIX utility is type
. The C Shell has a which command, and some systems have it as an external executable. For instance, on Debian Linux, which
comes from a package called debutils
. This external which
does not "see" shell built-ins, aliases or functions. type
does; Bash's type
has an option to suppress that and just do a path lookup.
– Kaz
Apr 17 '15 at 16:09
Windows Server 2003 and later (i.e. anything after Windows XP 32 bit) provide the where.exe
program which does some of what which
does, though it matches all types of files, not just executable commands. (It does not match built-in shell commands like cd
.) It will even accept wildcards, so where nt*
finds all files in your %PATH%
and current directory whose names start with nt
.
Try where /?
for help.
Note that Windows PowerShell defines where
as an alias for the Where-Object
cmdlet, so if you want where.exe
, you need to type the full name instead of omitting the .exe
extension.
where.exe
is not a shell builtin, you need to have %windir%\system32
on your %PATH%
- which may not be the case, as using where
suggests that you may be working on problems with your path!
– Tomasz Gandor
Jul 8 '15 at 9:00
While later versions of Windows have a where
command, you can also do this with Windows XP by using the environment variable modifiers, as follows:
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
You don't need any extra tools and it's not limited to PATH
since you can substitute any environment variable (in the path format, of course) that you wish to use.
And, if you want one that can handle all the extensions in PATHEXT (as Windows itself does), this one does the 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
It actually returns all possibilities but you can tweak it quite easily for specific search rules.
which
back in W95/DOS days amdittedly, the search order was - current dir, then each path dir, for cmd.com, then cmd.exe, then cmd.bat So, even cmd.bat in current dir is executed befroe cmd.exe soemwhere in path
– Mawg says reinstate Monica
Mar 26 '10 at 0:46
@echo off for %%i in (%1) do @echo. %%~$PATH:%i
To add it to an alias.bat script that you load everytime you run cmd.exe (put the above script in a new directory called C:\usr\aliases): DOSKEY which=C:\usr\aliases\which.bat $*
Then you can make a script to launch cmd.exe with the alias.bat file: cmd.exe /K E:\usr\aliases\alias.bat
– Brad T.
Apr 25 '14 at 20:42
Under PowerShell, Get-Command
will find executables anywhere 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
It also finds PowerShell cmdlets, functions, aliases, files with custom executables extensions via $Env:PATHEXT
, etc. defined for the current shell (quite akin to Bash's type -a foo
) - making it a better go-to than other tools like where.exe
, which.exe
, etc which are unaware of these PowerShell commands.
Finding executables using only part of the name
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 custom executables
To find other non-windows executables (python, ruby, perl, etc), file extensions for those executables need to be added to the PATHEXT
environmental variable (defaults to .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
) to identify files with these extensions in the PATH
as executable. As Get-Command
also honours this variable, it can be extended to list custom executables. e.g.
$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
You can quickly set up an alias with sal which gcm
(short form of set-alias which get-command
).
More information and examples can be found under the online help for Get-Command
.
.BAT
, .CMD
, etc), they are considered executable because their extensions are named in the PATHEXT
variable (which by default is PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
). Other executable types (e.g. .py
, .rb
, etc) can be added by adding the file extension in and creating an executable association with assoc
/ftype
- e.g. docs.python.org/3.3/using/…
– shalomb
Jan 6 '19 at 21:19
In Windows PowerShell:
set-alias which where.exe
If you have PowerShell installed (which I recommend), you can use the following command as a rough equivalent (substitute programName for your executable's name):
($Env:Path).Split(";") | Get-ChildItem -filter programName*
More is here: My Manwich! PowerShell Which
($Env:Path).Split(";") | Get-ChildItem -filter programName*
is so easy to type... ;-)
– Craig
Nov 30 '14 at 8:56
The GnuWin32 tools have which
, along with a whole slew of other Unix tools.
In Windows CMD which
calls where
:
$ where php
C:\Program Files\PHP\php.exe
Cygwin is a solution. If you don't mind using a third-party solution, then Cygwin is the way to go.
Cygwin gives you the comfort of *nix in the Windows environment (and you can use it in your Windows command shell, or use a *nix shell of your choice). It gives you a whole host of *nix commands (like which
) for Windows, and you can just include that directory in your PATH
.
In PowerShell, it is gcm
, which gives formatted information about other commands. If you want to retrieve only path to executable, use .Source
.
For instance: gcm git
or (gcm git).Source
Tidbits:
- Available for Windows XP.
- Available since PowerShell 1.0.
gcm
is an alias ofGet-Command
cmdlet.- Without any parameters, it lists down all the available commands offered by the host shell.
- You can create a custom alias with
Set-Alias which gcm
and use it like:(which git).Source
. - Official docs: https://technet.microsoft.com/en-us/library/ee176842.aspx
I have a function in my PowerShell profile named 'which'
function which {
get-command $args[0]| format-list
}
Here's what the output looks like:
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:
> get-command app.exe | format-list
worked perfectly!
– Alexander McFarlane
Jul 16 '18 at 9:30
Go get unxutils from here: http://sourceforge.net/projects/unxutils/
gold on windows platforms, puts all the nice unix utilities on a standard windows DOS. Been using it for years.
It has a 'which' included. Note that it's case sensitive though.
NB: to install it explode the zip somewhere and add ...\UnxUtils\usr\local\wbin\ to your system path env variable.
.
for the \r. It's a 99% solution though for sure!
– dash-tom-bang
Jul 28 '15 at 20:01
If you can find a free Pascal compiler, you can compile this. At least it works and shows the algorithm necessary.
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.
my_funk;
is unecessary. Thanks for posting a Pascal program, reminds me of my youth! It is such a pity that Pascal did not evolve.
– yannis
Aug 27 '15 at 8:41
Not in stock Windows but it is provided by Services for Unix and there are several simple batch scripts floating around that accomplish the same thing such this this one.
The best version of this I've found on Windows is Joseph Newcomer's "whereis" utility, which is available (with source) from his site.
The article about the development of "whereis" is worth reading.
None of the Win32 ports of Unix which that I could find on the Internet are satistactory, because they all have one or more of these shortcomings:
- No support for Windows PATHEXT variable. (Which defines the list of extensions implicitely added to each command before scanning the path, and in which order.) (I use a lot of tcl scripts, and no publicly available which tool could find them.)
- No support for cmd.exe code pages, which makes them display paths with non-ascii characters incorrectly. (I'm very sensitive to that, with the ç in my first name :-))
- No support for the distinct search rules in cmd.exe and the PowerShell command line. (No publicly available tool will find .ps1 scripts in a PowerShell window, but not in a cmd window!)
So I eventually wrote my own which, that suports all the above correctly.
Available there: http://jf.larvoire.free.fr/progs/which.exe
This batch file uses CMD variable handling to find the command that would be executed in the path. Note: that the current directory is always done before the path) and depending on which API call is used other locations are searched before/after the path.
@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%)
See set /?
for help.
You can first install Git from Downloading Git, and then open Git Bash and type:
which app-name
I am using GOW (GNU on Windows) which is a light version of Cygwin. You can grab it from GitHub here.
GOW (GNU on Windows) is the lightweight alternative to Cygwin. It uses a convenient Windows installer that installs about 130 extremely useful open source UNIX applications compiled as native win32 binaries. It is designed to be as small as possible, about 10 MB, as opposed to Cygwin which can run well over 100 MB depending upon options. - About Description(Brent R. Matzelle)
A screenshot of a list of commands included in GOW:
I have created tool similar to Ned Batchelder:
Searching .dll and .exe files in PATH
While my tool is primarly for searching of various dll versions it shows more info (date, size, version) but it do not use PATHEXT (I hope to update my tool soon).
For you Windows XP users (who have no where
command built-in), I have written a "where like" command as a rubygem called whichr
.
To install it, install Ruby.
Then
gem install whichr
Run it like:
C:> whichr cmd_here
TCC and TCC/LE from JPSoft are CMD.EXE replacements that add significant functionality. Relevant to the OP's question, which
is a builtin command for TCC family command processors.
I have used the which
module from npm for quite a while, and it works very well: https://www.npmjs.com/package/which
It is a great multi platform alternative.
Now I switched to the which
that comes with Git. Just add to your path the /usr/bin
path from Git, which is usually at C:\Program Files\Git\usr\bin\which.exe
. The which
binary will be at C:\Program Files\Git\usr\bin\which.exe
. It is faster and also works as expected.
Just have to post this Windows' one liner batch file:
C:>type wh.cmd
@for %%f in (%*) do for %%e in (%PATHEXT% .dll .lnk) do for %%b in (%%f%%e) do for %%d in (%PATH%) do if exist %%d\%%b echo %%d\%%b
A test:
C:>wh ssh
C:\cygwin64\bin\ssh.EXE
C:\Windows\System32\OpenSSH\\ssh.EXE
Not quite a one-liner if you wrap the code in setlocal enableextensions
and endlocal
.
try this
set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
Michael mentions this - the command in Vista is 'where'
Use powershell. If your on windows and your still using the standard cmd shell you need to switch.
http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx
I recommend it for it's acceptance of 'ls' alone.
Anyway, it has which.
PS D:\> which python.exe
C:\Python26/python.exe
You can a batch file having only 90 bytes from here: http://blogs.msdn.com/b/oldnewthing/archive/2005/01/20/357225.aspx
Or run a C# Program - a link is placed on the website above.
I found this batch file very handy
http://pankaj-k.net/weblog/2004/11/equivalent_of_which_in_windows.html
Sorry to chip in on an old thread, but as some third-party solutions have been suggested, I just have to give a shoutout to Cmder.
It's a ComEmu-based console that has a fairly comprehensive bash shell, including commands like which and grep. The only issue is that the conemu paths are added to the start of your %PATH%, so commands that are common to DOS and UNIX (like find) default to the UNIX version. It's easy to edit the init.bat file to avoid this though.
NLP :)
C:\> where are mspaint and notepad and... where is where actually? 2>nul
Output:
C:\Windows\System32\mspaint.exe
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe
C:\Windows\System32\where.exe
Did you try obtaining unixcmds.zip? It should have a copy of which.exe in it.
There isn't one built in, but you can use a Python script: wh.py
Not as a command line command there isn't. That info IS stored in the Registry, but it takes a a little bit effort to drag it out.
Get the weekly newsletter! In it, you'll get:
- The week's top questions and answers
- Important community announcements
- Questions that need answers
see an example newsletter
Linked
Related
Hot Network Questions
-
Should I use AND in function name?
-
Spherical Polar Diagram
-
How to add two numbers from a group theoretic perspective?
-
Why did Mace Windu and the Jedi Council refuse to raise Anakin to the rank of Master?
-
Why won't Delta Airlines sell me a ticket for a trip entirely within Canada?
-
Is it necessary to pay extra for navigation when renting a car in the US?
-
Is it safe to stack Mac minis on top of each other?
-
What is a "monster knight"?
-
Is Libertarianism left wing or right wing?
-
What type of subfloor will stand up to water in a bathroom?
-
Would you notice, visually, if the planet you were on was vastly larger than Earth?
-
hyphenation: what special is in word "implementation"
-
I'm a remorseless killer
-
Extent of "unscientific" or wrong papers in research mathematics
-
Is there a maximum result size for @AuraEnabled Apex methods for Lightning Aura components?
-
Rotating a concrete slab?
-
What is Dark Speech?
-
My friend cosigned for a defaulted loan. Should he declare Chapter 7 bankruptcy?
-
Why aren't the Congressional limits on press coverage during the Trump impeachment trial considered a breach of the first amendment?
-
One piece of a destroyed chess board
-
What happens when a town is under quarantine and my visa expires
-
Did I lie on my resume by not mentioning that I did not spend enough time at university to qualify for a degree?
-
Reasons a fictitious metal is really hard to refine?
-
Why does the Wuhan coronavirus genome end in aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (33 a's)?
site design / logo © 2020 Stack Exchange Inc; user contributions licensed under cc by-sa 4.0 with attribution required. rev 2020.1.24.35891