コマンドがバッチファイルで認識されているかどうかを判断する


43

プログラム(javacなど)を呼び出すbatスクリプトを書いています。簡単にするために、実行する前にコマンドが存在するかどうかを確認したいと思います。すなわち、コマンドがPATHに存在する場合。

例えば、

if (my_command.exe is a recognized command) then (
  my_command.exe my_args
) else (
  REM Output was probably "'my_command.exe' is not recognized as an internal or external command, operable program or batch file."
  REM Do not run my_command.exe
)

Windowsでこれを行う最良の方法は何ですか?


コマンドをどのように「認識」しますか?
ルーク

MS-DOS(真のDOS)では、これはかなり単純でした。c:\ dos内のexeファイルの存在を確認しました。しかし、それでも問題は残っています。
ルーク

混乱させて申し訳ありません。私は本質的にWindowsのコマンドプロンプトを意味していました。「lkajsflksajdfj」と入力すると、コマンドではないことがわかります。「notepad.exe」と入力すれば、問題ありません。
user46097

回答:


54
WHERE mycommand
IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 

10
誰かがcmdウィンドウ内の出力を望まない場合は、の>nul 2>nul後ろに追加するだけmycommandです。
セバスチャン

1と2よりも多くの出力チャネルがあることに注意してください。1は出力バッファーを表し、2はエラーバッファーを表します。アプリケーションの開発方法によって異なります。チャンネル1と2がリダイレクトされた場合でもテキストをスローします。
ElektroStudios

15

以下のコードは、ガベージ出力なしで常にきれいに実行する必要があります。

javac -version >nul 2>&1 && (
    echo found javac
) || (
    echo fail
)

出力:

found javac

ワンライナーと同じコード:

javaz -version >nul 2>&1 && ( echo found javac ) || ( echo fail )

出力:

fail

それは順序をメモ&&して||も問題のようです。また、存在をテストするコマンドは、これが機能するためにerrorlevel <= 0で返される必要があります。コマンドに/?または--help引数、またはjavaと同様に、バージョン情報コマンド。


このソリューションは完璧です!
robe007

7

最も簡単な方法は単純にコマンドを実行することですが、もちろん、ランダムプロセスを開始したくない場合があるため、他の問題もあります。

for %%x in (my_command.exe) do if not [%%~$PATH:x]==[] set MyCommandFound=1

%PATH%環境変数によってリストされたパスでプログラムを検索する代替手段です。これは本質的にの純粋なバッチバージョンですwhich(1)。より良くすることができますが、本質的にはこれです。


1
これは完璧で、要求されたとおりに機能します!
ペッツカッコウ

3

私の状況のた​​めに。絶対的な最も簡単な方法は||を使用することです または&&演算子。

my_command.exe -version 2>NUL && echo "my_command exists"

または

my_command.exe -version 2>NUL || echo "my_command doesn't exist"

なぜ標準出力もリダイレクトしないのですか?
ジョーイ

3

以下のバージョンにいくつかの改良。コマンドが存在することをテストし、不要な出力を抑制します。

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found

ここで、<my_exe> NUL 2>&1 || echo my.exeは存在しません&& goto:EOFはスクリプトでうまく動作します
ロバート

注意:テストするファイル名にパス情報が含まれている場合、これは機能しません。例、WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
ジョナサンギルバート

1

追加のツールのインストールが必要な場合whereは、リソースキットにコマンドがあります。whereisに相当するWindowsを参照してください

それ以外の場合、Windowsのバージョンが古すぎない場合、PATH以外のDos実行可能ルックアップで説明cmdされているように、pure で実行可能です。


返事をありがとう!残念ながら、要件の1つは、バニラボックス(XPマシンを含む)で実行する必要があることです。したがって、whereisはオプションではありません。
user46097

2
Gillesが提供した2番目のリンクには、FORを使用し、追加のツールを使用しない優れたソリューションがあります。
パラドロイド

1

私はこれがあなたが探しているものではないことを知っていますが、ロジックをわずかに変更するだけで、あなたが必要とするものを達成するはずです。

実行されるすべてのコマンドにはリターンコード(エラーレベルとも呼ばれます)があり、リターンコードが0(ゼロ)の場合、コマンドは正常に実行され、リターンコードが0より大きい場合、何かが間違っています。

詳細はこちらをご覧ください。

何かのようなもの -

my_command
if (%ERRORLEVEL% > 0) then (
  REM Output was probably "'my_command.exe' is not recognized as an internal or external command, operable program or batch file.  OR SOMETHING WENT WRONG WITH IT."
  REM Do not run my_command.exe
)

これは賢いです、私はそれが好きです。
Shinrai

ええ、しかしいのは、コマンドが見つからない場合、2行のエラーがスローされるからです。したがって、よりクリーンなソリューションが見つかる可能性があります。
djangofan

0

これらの方法はすべて機能する可能性がありますが、組み込みの方法はどうですか?

If exists my_command do echo "my_command exists"

「if /?」を実行します 詳細については、コマンドラインで


5
これは、その名前のファイル/ディレクトリが現在のディレクトリに存在するかどうかのみを調べます。を検索する必要があると判断するため、その名前の実行可能なコマンドが存在するかどうかのヒントはあまり提供されませんPATH
ジョーイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.