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

后端 未结 26 2047
悲哀的现实
悲哀的现实 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: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.
    

提交回复
热议问题