Is there an equivalent of 'which' on the Windows command line?

后端 未结 26 2030
悲哀的现实
悲哀的现实 2020-11-22 00:40

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 pa

相关标签:
26条回答
  • 2020-11-22 00:40

    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.

    0 讨论(0)
  • 2020-11-22 00:40

    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

    0 讨论(0)
  • 2020-11-22 00:41

    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.

    0 讨论(0)
  • 2020-11-22 00:42

    In Windows CMD which calls where:

    $ where php
    C:\Program Files\PHP\php.exe
    
    0 讨论(0)
  • 2020-11-22 00:42

    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.
    
    0 讨论(0)
  • 2020-11-22 00:42

    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.

    0 讨论(0)
提交回复
热议问题