web-dev-qa-db-ja.com

Windowsのコマンドラインに「which」と同等のものはありますか?

私は自分のcmdスクリプトの1つが他のプログラムによって隠されている(パス上で)パスの問題を抱えているので、与えられたWindowsコマンドラインでプログラムへのフルパスを見つけたいと思います。その名前だけです。

UNIXのコマンド「which」に相当するものはありますか?

UNIXでは、which commandは与えられたコマンドのフルパスを表示して、これらのシャドーイング問題を簡単に見つけて修復します。

2107
namin

Windows Server 2003以降(つまり、Windows XP 32ビット以降)は、実行可能コマンドだけでなく、すべての種類のファイルに一致しますが、whichの機能の一部を実行するwhere.exeプログラムを提供します。 (cdのような組み込みのシェルコマンドとは一致しません。)ワイルドカードも受け入れます。したがって、where nt*は、%PATH%および現在のディレクトリ内でntで始まるすべてのファイルを検索します。

助けを得るためにwhere /?を試してください。

Windows PowerShellではwhereWhere-Objectコマンドレット のエイリアスとして定義されているため、where.exeが必要な場合は、.exe拡張子を省略するのではなくフルネームを入力する必要があります。

2313

最近のバージョンの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

それは実際にはすべての可能性を返しますが、特定の検索ルールに合わせて簡単に微調整できます。

274
paxdiablo

Windows PowerShellの場合

set-alias which where.exe
51
cmcginty

PowerShellがインストールされている場合(これをお勧めします)、次のコマンドを大まかに同等のものとして使用できます(実行可能ファイルの名前の代わりにprogramNameを使用してください)。

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

もっとここにあります:私のManwich! PowerShellこれは

38
RexE

GnuWin32 ツールは他にもたくさんの他のUnixツールと共にwhichを持っています。

33
Ferruccio

Windows CMDでは、whichwhereを呼び出します。

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

Cygwin は解決策です。サードパーティのソリューションを使用しても構わない場合は、Cygwinが最適な方法です。

Cygwinは、Windows環境で* nixの快適さを提供します(そして、あなたはあなたのWindowsコマンドシェルでそれを使うことができます、あるいはあなたが選んだ* nixシェルを使うことができます)。それはあなたにWindows用のwhichのような* nixコマンドの全部のHostを与えます、そしてあなたはあなたのPATHにそのディレクトリを含めることができます。

16
palswim

PowerShellでは、それはgcmです。これは、他のコマンドに関するフォーマットされた情報を提供します。実行可能ファイルへのパスのみを取得したい場合は、.Sourceを使用してください。

例えば、gcm gitまたは(gcm git).Sourceです。

ちょっとしたこと:

  • Windows XPで利用可能です。
  • PowerShell 1.0以降で利用可能です。
  • gcmGet-Command cmdlet のエイリアスです。
  • パラメータを指定しないと、ホストシェルによって提供される利用可能なすべてのコマンドが一覧表示されます。
  • Set-Alias which gcmを使ってカスタムエイリアスを作成して、(which git).Sourceのように使うことができます。
  • 公式ドキュメント: https://technet.Microsoft.com/ja-jp/library/ee176842.aspx
12
vulcan raven

PowerShellプロファイルに「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:
10
Fez

ここからunxutilsを入手してください: http://sourceforge.net/projects/unxutils/ /

windowsプラットフォームでは、すべてのNice unixユーティリティが標準Windows DOSに配置されています。何年も使っています。

「which」が含まれています。ただし、大文字と小文字は区別されます。

注意:インストールするにはZipをどこかに展開し、システムパスのenv変数に...\UnxUtils\usr\local\wbin \を追加します。

9
Jon Court

あなたが無料の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.
8
Mawg

Windowsにはありませんが、 Services for Unix で提供されています。これは、this this one のような同じことを実現する簡単なバッチスクリプトがいくつかあります。

7
Robert Gamble

私がWindowsで見つけたこの最高のバージョンは、 彼のサイト から(ソース付きで)利用可能なJoseph Newcomerの "whereis"ユーティリティです。

"whereis"の開発に関する記事は読む価値があります。

7
Tim Lesher

このバッチファイルは、パス内で実行されるコマンドを見つけるために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 /?を参照してください。

6
user6017774

私がインターネット上で見つけることができるUnixのWin32ポートはどれも満足のいくものではありません。それらはすべて1つ以上のこれらの欠点があるからです。

  • WindowsのPATHEXT変数はサポートされていません。 (これは、パスをスキャンする前に各コマンドに暗黙的に追加される拡張子のリストを定義し、その順序で定義しています。)
  • Cmd.exeコードページはサポートされていません。これにより、ASCII以外の文字を含むパスが誤って表示されます。 (私の名前にçが付いているので、私はそれに非常に敏感です:-))
  • Cmd.exeおよびPowerShellコマンドラインでの個別の検索ルールはサポートされていません。 (公に利用可能なツールは、PowerShellウィンドウに.ps1スクリプトを見つけることはできませんが、cmdウィンドウにはありません!)

それで私は結局私自身のものを書いた、それは上のすべてを正しく支持する。

そこに利用可能: http://jf.larvoire.free.fr/progs/which.exe

Cygwinの軽量版であるGOW(Windows上のGNU)を使用しています。 GitHubから入手できます ここ

GOW(Windows上のGNU)はCygwinに代わる軽量のものです。それはネイティブのwin32バイナリとしてコンパイルされた約130の非常に役に立つオープンソースのUNIXアプリケーションをインストールする便利なWindowsインストーラを使います。 Cygwinはオプションによっては100 MBをはるかに超えて実行できるのではなく、可能な限り小さく、約10 MBになるように設計されています。 - 説明について(Brent R. Matzelle)

GOWに含まれているコマンドのリストのスクリーンショット:

Enter image description here

6

Ned Batchelderに似たツールを作成しました。

PATHで.dllファイルと.exeファイルを検索する

私のツールは主にさまざまなdllバージョンを検索するためのものですが、それはより多くの情報(日付、サイズ、バージョン)を表示しますが、それはPATHEXTを使用しません(私はすぐに私のツールをアップデートしたいです)。

5
Michał Niklas

最初にからGitをインストールし、次にGitをダウンロードしてからGit Bashを開いて次のように入力します。

which app-name
5

whereコマンドが組み込まれていないWindows XPユーザーのために、私はwhichrと呼ばれるrubygemとして "where like"コマンドを書きました。

インストールするには、Rubyをインストールしてください。

それから

gem install whichr

実行してください:

C:> whichr cmd_here

3
rogerdpack

JPSoftのTCCおよびTCC/LEは、重要な機能を追加するCMD.EXEの代替品です。 OPの質問に関連して、whichはTCCファミリーのコマンドプロセッサ用の組み込みコマンドです。

3
David G

私はしばらくの間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になります。それは速く、そしてまた期待通りに働く。

2
Giovanni Bassi

これを試して

set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
1
FeZZo