由于我有时遇到路径问题,其中一个我自己的cmd脚本被另一个程序隐藏(阴影)(在路径的前面),我希望能够在Windows命令中找到程序的完整路径这条线,只是它的名字。
是否有与UNIX命令相同的'哪个'?
在UNIX上,which command
打印给定命令的完整路径,以便轻松查找和修复这些阴影问题。
答案 0 :(得分:2325)
Windows Server 2003及更高版本(即Windows XP 32位之后的任何内容)提供where.exe
程序,它执行which
所做的一些操作,尽管它匹配所有类型的文件,而不仅仅是可执行命令。 (它与cd
等内置shell命令不匹配。)它甚至会接受通配符,因此where nt*
会查找%PATH%
和当前目录中名称以{{1开头的所有文件}}
尝试nt
寻求帮助。
请注意,Windows PowerShell将where /?
定义为the Where-Object
cmdlet的别名,因此如果您需要where
,则需要输入全名而不是省略where.exe
扩展名
答案 1 :(得分:274)
虽然Windows的更高版本具有where
命令,但您也可以使用环境变量修饰符在Windows XP中执行此操作,如下所示:
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
您不需要任何额外的工具,它不仅限于PATH
,因为您可以替换您希望使用的任何环境变量(当然是路径格式)。
而且,如果你想要一个可以处理PATHEXT中所有扩展的东西(就像Windows本身那样),那么这个就可以了:
@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
它实际上返回了所有可能性,但您可以轻松地针对特定搜索规则进行调整。
答案 2 :(得分:129)
在PowerShell下,Get-Command
会在$Env:PATH
中找到可执行文件。
Get-Command eventvwr
CommandType Name Definition
----------- ---- ----------
Application eventvwr.exe c:\windows\system32\eventvwr.exe
Application eventvwr.msc c:\windows\system32\eventvwr.msc
它还可以找到PowerShell cmdlet,函数,别名,带有$Env:PATHEXT
自定义可执行文件扩展名的文件,等等,为当前shell定义(非常类似于Bash&#39; s type -a foo
) - 制作它比where.exe
,which.exe
等其他工具更好,这些工具不知道这些PowerShell命令。
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
...
要查找其他非Windows可执行文件(python,ruby,perl等),需要将这些可执行文件的文件扩展名添加到PATHEXT
环境变量(默认为.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
)以标识文件将PATH
中的这些扩展名作为可执行文件。由于Get-Command
也尊重此变量,因此可以将其扩展为列出自定义可执行文件。 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
您可以使用sal which gcm
(set-alias which get-command
的缩写形式)快速设置别名。
更多信息和示例可在Get-Command
的在线帮助下找到。
答案 3 :(得分:52)
在Windows PowerShell中:
set-alias which where.exe
答案 4 :(得分:38)
如果你安装了PowerShell(我推荐),你可以使用以下命令作为粗略的等价物(替换你的可执行文件名的programName):
($Env:Path).Split(";") | Get-ChildItem -filter programName*
更多信息在这里: My Manwich! PowerShell Which
答案 5 :(得分:34)
GnuWin32工具有which
,以及大量其他Unix工具。
答案 6 :(得分:24)
在Windows CMD中which
调用where
:
$ where php
C:\Program Files\PHP\php.exe
答案 7 :(得分:17)
Cygwin是一个解决方案。如果您不介意使用第三方解决方案,那么Cygwin就是您的选择。
Cygwin在Windows环境中为您提供了* nix的舒适感(您可以在Windows命令shell中使用它,或者使用您选择的* nix shell)。它为Windows提供了大量* nix命令(如which
),您可以在PATH
中包含该目录。
答案 8 :(得分:12)
在PowerShell中,它是gcm
,它提供有关其他命令的格式化信息。如果您只想检索可执行文件的路径,请使用.Source
。
例如:gcm git
或(gcm git).Source
小知识:
gcm
是Get-Command
cmdlet的别名。Set-Alias which gcm
创建自定义别名,并将其用作:(which git).Source
。答案 9 :(得分:10)
我的PowerShell配置文件中有一个名为&#39;&#39;
的功能function which {
get-command $args[0]| format-list
}
这是输出的样子:
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 :(得分:9)
从这里获取unxutils:http://sourceforge.net/projects/unxutils/
Windows平台上的黄金,将所有漂亮的unix实用程序放在标准的Windows DOS上。多年来一直在使用它。它包含'哪个'。请注意,它虽然区分大小写。
注意:安装它会在某处爆炸zip并将... \ UnxUtils \ usr \ local \ wbin \添加到系统路径env变量中。
答案 11 :(得分:8)
如果你能找到一个免费的Pascal编译器,你可以编译它。至少它起作用并显示必要的算法。
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.
答案 12 :(得分:7)
我在Windows上找到的最好的版本是Joseph Newcomer的“whereis”实用程序,可以从his site获得(来源)。
关于“whereis”发展的文章值得一读。
答案 13 :(得分:7)
没有库存的Windows,但它由Services for Unix提供,并且有几个简单的批处理脚本可以完成相同的操作,例如this one。
答案 14 :(得分:6)
我在互联网上找到的Unix的Win32端口都不是satistactory,因为它们都有一个或多个这些缺点:
所以我最终写了我自己的,这正确地支持了以上所有。
答案 15 :(得分:6)
此批处理文件使用CMD变量处理来查找将在路径中执行的命令。注意:当前目录总是在路径之前完成,并且根据使用的API调用,在路径之前/之后搜索其他位置。
@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%)
请参阅set /?
寻求帮助。
答案 16 :(得分:6)
您可以先从 Downloading Git 安装Git,然后打开Git Bash并输入:
which app-name
答案 17 :(得分:6)
我正在使用GOW(Windows上的GNU),这是Cygwin的简易版本。你可以从GitHub here中获取它。
GOW(Windows上的GNU)是Cygwin的轻量级替代品。它用 一个方便的Windows安装程序,安装大约130个极端 编译为本机win32的有用的开源UNIX应用程序 二进制文件。它的设计尽可能小,大约10 MB,如 与Cygwin相反,Cygwin可以运行超过100 MB,具体取决于 选项。 - About Description(Brent R. Matzelle)
GOW中包含的命令列表的屏幕截图:
答案 18 :(得分:5)
我创建了类似于Ned Batchelder的工具:
Searching .dll and .exe files in PATH
虽然我的工具主要用于搜索各种dll版本,但它显示更多信息(日期,大小,版本),但它不使用PATHEXT(我希望尽快更新我的工具)。
答案 19 :(得分:4)
对于Windows XP用户(内置没有where
命令的用户),我编写了一个“where like”命令作为名为whichr
的rubygem。
要安装它,请安装Ruby。
然后
gem install whichr
像以下一样运行:
C:&GT;哪个cmd_here
答案 20 :(得分:3)
which
是TCC系列命令处理器的内置命令。
答案 21 :(得分:2)
我使用了npm的which
模块已经有一段时间了,而且效果非常好:https://www.npmjs.com/package/which
这是一个很好的多平台替代方案。
现在我切换到Git附带的which
。只需在Git中添加/usr/bin
路径,通常位于C:\Program Files\Git\usr\bin\which.exe
。 which
二进制文件位于C:\Program Files\Git\usr\bin\which.exe
。它更快,也可以按预期工作。
答案 22 :(得分:2)
只需发布此Windows的一个班轮批处理文件:
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
测试:
C:>wh ssh
C:\cygwin64\bin\ssh.EXE
C:\Windows\System32\OpenSSH\\ssh.EXE
如果将代码包装在setlocal enableextensions
和endlocal
中,则不是一味的方法。
答案 23 :(得分:1)
尝试
set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
答案 24 :(得分:0)
可以从以下GitHub存储库中下载所有为Windows编译的UNIX命令,包括which
:https://github.com/George-Ogden/UNIX
答案 25 :(得分:-1)
这里是我用来查找可执行文件的功能,类似于Unix命令'WHICH`
app_path_func.cmd:
@ECHO OFF
CLS
FOR /F "skip=2 tokens=1,2* USEBACKQ" %%N IN (`reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\%~1" /t REG_SZ /v "Path"`) DO (
IF /I "%%N" == "Path" (
SET wherepath=%%P%~1
GoTo Found
)
)
FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe %~1`) DO (
SET wherepath=%%F
GoTo Found
)
FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%PROGRAMFILES%" %~1`) DO (
SET wherepath=%%F
GoTo Found
)
FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%PROGRAMFILES(x86)%" %~1`) DO (
SET wherepath=%%F
GoTo Found
)
FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%WINDIR%" %~1`) DO (
SET wherepath=%%F
GoTo Found
)
:Found
SET %2=%wherepath%
:End
测试:
@ECHO OFF
CLS
CALL "app_path_func.cmd" WINWORD.EXE PROGPATH
ECHO %PROGPATH%
PAUSE
结果:
C:\Program Files (x86)\Microsoft Office\Office15\
Press any key to continue . . .