在Windows命令行中是否有相当于“哪个”?

由于我有时遇到了path问题,我的一个cmd脚本被其他程序(path上的较早)隐藏(隐藏),我希望能够在Windows命令行上find程序的完整path,只是它的名字。

有没有相当于UNIX命令“哪个”?

在UNIX上, which command打印给定命令的完整path以轻松find并修复这些影子问题。

Windows Server 2003和更高版本(即Windows XP 32位之后的任何内容)提供了执行某些操作的where.exe程序,尽pipe它匹配所有types的文件,而不仅仅是可执行的命令。 (它与cd类的内置shell命令不匹配。)它甚至会接受通配符,所以where nt*%PATH%和当前目录中查找名称以nt开头的所有文件。

尝试where /? 求助。

请注意,Windows PowerShell将Where-Object作为Where-Object cmdlet的别名进行定义,因此如果需要where.exe ,则需要input完整名称而不是省略.exe扩展名。

尽pipe更高版本的Windows具有一个where命令,但也可以使用环境variables修饰符在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因为你可以用你想使用的任何环境variables(当然是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 

它实际上返回所有的可能性,但你可以很容易地调整它的具体search规则。

在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 

它还通过为当前shell定义的$Env:PATHEXT等自定义可执行文件扩展名findpowershell cmdlet,函数,别名,文件(类似于bash的type -a foo ) – 使得它比其他工具更好where.exewhich.exe等不知道这些PowerShell命令。

你可以快速设置一个别名, sal which gcmset-alias which get-commandset-alias which get-command简写forms)。

在Windows PowerShell中:

 set-alias which where.exe 

如果你安装了PowerShell(我build议),你可以使用下面的命令作为一个粗略的等价物(用可执行文件的名称替代programName):

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

更多信息: http : //www.codeassassin.com/blog/PermaLink,guid,fd1967d1-f844-4e29-82e2-f2d6424b4ef9.aspx

GnuWin32工具和其他一些Unix工具一起使用。

在Windows CMD which调用where

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

惊讶的是没有人提到cygwin作为解决scheme。 如果你不介意使用第三方解决scheme,那么cygwin是要走的路。

Cygwin在Windows环境中为您提供* nix的舒适(您可以在Windows命令shell中使用它,或使用您select的* nixshell)。 它为你提供了大量的* nix命令(比如which ),你可以在PATH包含这个目录。

在PowerShell中,它是gcm ,它提供了有关其他命令的格式化信息。 如果您只想检索可执行文件的path,请使用.Source

例如: gcm git(gcm git).Source

小知识:

  • 适用于Windows XP。
  • 自PowerShell 1.0以来可用。
  • gcmGet-Command cmdlet的别名。
  • 没有任何参数,它列出主机shell提供的所有可用命令。
  • 你可以用Set-Alias which gcm创build一个自定义别名Set-Alias which gcm并使用它: (which git).Source
  • 官方文档: https : //technet.microsoft.com/en-us/library/ee176842.aspx

从这里得到unxutils: http : //sourceforge.net/projects/unxutils/

在Windows平台上的黄金,把所有漂亮的Unix工具在一个标准的Windows DOS上。 多年来一直使用它。

它包含一个“哪个”。 请注意,它是区分大小写的。

注意:要安装它将zip分解到某处并将… \ UnxUtils \ usr \ local \ wbin \添加到您的系统pathenvvariables中。

没有库存的Windows,但是它是由Unix提供的,有几个简单的批处理脚本可以完成同样的事情。

我在Windows上find的最好的版本是Joseph Newcomer的“whereis”工具,它可以从他的网站上find 。

关于“whereis”发展的文章值得一读。

我在我的PowerShellconfiguration文件中有一个名为'which'的函数,

 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: 

不知道,如果这有帮助。 作为回答发表,因为我不知道如何格式化代码的评论(帮助?)

如果你可以find一个免费的pascal编译器,你可以编译这个,或给我发电子邮件,我可以尝试挖出一个,或邮寄回EXE或张贴在某个地方。 我发布的代码,不好的,因为至less它工作和显示algorithm必要的。

 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 existance 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 eg '); Writeln('"my_cmd.exe param"'); Write ('then invoke Whence with the same extension eg '); 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 { OK, 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 thru 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. 

我创build了类似于Ned Batchelder的工具:

在PATH中search.dll和.exe文件

虽然我的工具主要是search各种dll版本,它显示更多的信息(date,大小,版本),但它不使用PATHEXT(我希望很快更新我的工具)。

在因特网上找不到的Unix的Win32端口都没有,因为它们都有一个或多个这样的缺点:

  • 不支持Windows PATHEXTvariables。 (它定义了在扫描path之前隐式添加到每个命令中的扩展名列表,以及以何种顺序)。(我使用了大量的tcl脚本,没有公开提供哪个工具可以find它们。
  • 不支持cmd.exe代码页,这使得它们不正确地显示非ASCII字符的path。 (我对此非常敏感,ç以我的名字:-))
  • 不支持cmd.exe和PowerShell命令行中不同的search规则。 (没有公开的工具可以在PowerShell窗口中find.ps1脚本,但不能在cmd窗口中find!)

所以我最终写了我自己的,这正确地支持以上所有。

在那里可用: http : //jf.larvoire.free.fr/progs/which.exe

此batch file使用CMDvariables处理来查找将在path中执行的命令。 注意:当前目录总是在path之前完成),并且取决于使用哪个API调用,在path之前/之后search其他位置。

 @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 /? 求助。

您可以先从https://git-scm.com/download/win安装git,然后打开git bash并键入

 which app-name 

对于你的XP用户,我已经写了一个叫“ whichr ”的命令,叫做whichr

要安装它,请安装ruby

然后

gem install whichr

像运行一样

c:\>whichr cmd_here

来自JPSoft的TCC和TCC / LE是增加重要function的CMD.EXE替代品。 与OP的问题有关, which是TCC系列命令处理器的内置命令。