4

コマンドの名前があり、このコマンドが内部にあるかどうかを確認する必要があります。バッチスクリプトでそれを行うにはどうすればよいですか?

4

2 に答える 2

8

したがって、多くの調整を行った後、@ Andriy Mの助けを借りて、ようやく機能します。

@ECHO off

CALL :isInternalCommand dir dirInternal
ECHO is dir internal: %dirInternal%

CALL :isInternalCommand find findInternal
ECHO is find internal: %findInternal%

exit /b 0

:isInternalCommand
SETLOCAL

MKDIR %TEMP%\EMPTY_DIR_FOR_TEST > NUL 2>& 1
CD /D %TEMP%\EMPTY_DIR_FOR_TEST
SET PATH=
%~1 /? > NUL 2>&1
IF ERRORLEVEL 9009 (ENDLOCAL
SET "%~2=no"
) ELSE (ENDLOCAL
SET "%~2=yes"
)

GOTO :EOF

古いソリューション

を使用できますwhere。失敗した場合、コマンドはおそらく内部的なものです。成功すると、内部ではないことを証明する実行可能パスを取得します。

C:\Users\user>where path
INFO: Could not find files for the given pattern(s).

C:\Users\user>where find
C:\Windows\System32\find.exe

編集:コメントが示唆しているように、研究だけでなく携帯性を探しているのであれば、これは最善の解決策ではないかもしれません。だからここに別の可能な解決策があります。

何も設定%PATH%しないため、HELP何も見つからず、HELPチェックしようとしているコマンドで実行します。

C:\Users\user>set PATH=

C:\Users\user>path
PATH=(null)

C:\Users\user>%WINDIR%\System32\help del
Deletes one or more files.

DEL [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names
[...]

C:\Users\user>%WINDIR%\System32\help find
'find' is not recognized as an internal or external command,
operable program or batch file.

コマンドにヘルプがない場合でも、これは失敗する可能性があります。

編集2:気にしないでください、これも機能しません。どちらの場合も。を返し%ERRORLEVEL%=1ます。

于 2012-11-02T18:45:43.950 に答える
3

kichik は良い答えを持っています。ただし、指定されたコマンド名と一致する現在のディレクトリ内に実行可能ファイルまたはバッチ スクリプトが存在する場合は、誤検知が発生する可能性があります。

この問題を回避するために考えられる唯一の方法は、ディレクトリ内に空であることがわかっているフォルダーを作成し、%TEMP%そのフォルダーからテストを実行することです。

これは、動作するはずのkichikのソリューションの修正版です。

@echo off
setlocal

::Print the result to the screen
call :isInternal find
call :isInternal dir

::Save the result to a variable
call :isInternal find resultFind
call :isInternal dir  resultDir
set result

exit /b

:isInternal  command  [rtnVar]
setlocal
set "empty=%temp%\empty%random%"
md "%empty%"
pushd "%empty%"
set path=
>nul 2>nul %1 /?
if errorlevel 9009 (set rtn=not internal) else (set rtn=internal)
popd
rd "%empty%"
(
  endlocal
  if "%~2" neq "" (set %~2=%rtn%) else echo %1 is %rtn%
)
exit /b 0

HELP に内部コマンドの完全なリストが含まれていると仮定して、すべての内部コマンドを単純にリストするスクリプトを次に示します。

更新: FOR と IF の両方には、FOR 変数または遅延展開を介して実行された場合にこれらのコマンドが機能しないようにする特別な解析規則があります。このスクリプトを書き直して CALL を使用し、代わりに CALL 引数を介してコマンドを実行する必要がありました。

@echo off
setlocal enableDelayedExpansion
set "empty=%temp%\empty%random%"
md "%empty%"
pushd "%empty%"
for /f "delims= " %%A in ('help^|findstr /rc:"^[^ ][^ ]*  "') do call :test %%A
popd
rd "%empty%"
exit /b

:test
setlocal
set path=
%1 /? >nul 2>nul
if not errorlevel 9009 echo %1
exit /b 0
于 2012-11-03T01:37:07.917 に答える