我有一个命令的名称,我需要检查该命令是否是内部命令。我怎样才能在批处理脚本中做到这一点?
经过大量调整,并感谢@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
。
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
没有回答问题,但我列出了内置函数的列表(从
HELP.EXE
IIRC 的输出中提取它们)并按主题对它们进行分组(其他人可能会觉得有用或没用):
FOR REM MD CLS START
IF ECHO RD COLOR
GOTO PAUSE REN TITLE DATE
CALL MOVE PATH TIME
EXIT VOL DEL PROMPT VER
SET DIR COPY
SETLOCAL CD MKLINK ASSOC VERIFY
ENDLOCAL PUSHD TYPE FTYPE BREAK
SHIFT POPD
只有 38 个命令加上 5 个别名:
CD=CHDIR, MD=MKDIR, RD=RMDIR, DEL=ERASE, REN=RENAME
这个 43 个字符串的静态列表可用于检查命令是否是内置的(即使这不是 OP 的初衷)。