@echo offsetlocal 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=%%jcall :find_it %1!myext!
:: Remove the extension (not overly efficient but it works).
:loop2if 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
:endendlocalgoto :eof
:: Function to find and print a file in the path.
:find_itfor %%i in (%1) do set fullspec=%%~$PATH:iif not "x!fullspec!"=="x" @echo. !fullspec!goto :eof
Windows Server 2003及更高版本(即Windows XP 32位之后的任何内容)提供where.exe程序,该程序执行which的一些功能,尽管它匹配所有类型的文件,而不仅仅是可执行命令。(它不匹配像cd这样的内置shell命令。)它甚至可以接受通配符,所以where nt*可以找到%PATH%和当前目录中名称以nt开头的所有文件。
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. }beginif Fsearch(file_name, '') <> '' thenbeginWriteLn('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;
beginsemic_pos := Pos(';', path_str);if (semic_pos = 0) thenbeginGet_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) = '\') thenDelete(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) thenbeginWriteLn('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 <> '') thenbeginWriteLn('directory detected *', command_directory, '*');Halt(0);end;
if (command_extension <> '') thenbeginpath_str := Fsearch(paramstr(1), ''); { Current directory }if (path_str <> '') then WriteLn('Dos command = "', Fexpand(path_str), '"')elsebeginpath_str := Fsearch(paramstr(1), GetEnv('path'));if (path_str <> '') then WriteLn('Dos command = "', Fexpand(path_str), '"')else Writeln('command not found in path.');end;endelsebegin{ 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 <> '') dobeginCheck_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.
$ sal which gcm # short form of `Set-Alias which Get-Command`$ which foo...
PowerShell命令不仅仅是可执行文件(.exe、.ps1等)。它们还可以是cmdlet、函数、别名、$Env:PATHEXT中设置的自定义可执行后缀等。#3能够查找并列出所有这些命令(非常类似于Bash的type -a foo)。仅此一点就比where.exe、which.exe等更好,这些命令通常仅限于查找可执行文件。
@echo offecho.echo PathFind - Finds the first file in in a pathecho ======== = ===== === ===== ==== == == = ====echo.echo Searching for %1 in %path%echo.set a=%~$PATH:1If "%a%"=="" (Echo %1 not found) else (echo %1 found at %a%)
GOW(Windows上的GNU)是Cygwin的轻量级替代品。它使用一个方便的Windows安装程序,安装约130非常编译为原生win32的有用的开源UNIX应用程序二进制文件。它被设计为尽可能小,大约10 MB,因为与Cygwin相反,Cygwin可以运行超过100 MB,具体取决于选项。-关于描述(Brent R. Matzelle)