在批处理脚本中实施“which”命令

2024-01-06

我试图制作一个像这样的脚本which。所以我想检查这个命令是内部命令还是外部命令或两者兼而有之。我尝试执行程序,但是当程序(例如.exe)不正确时,我的程序退出时出现错误,所以我尝试调用help对于这个程序。但现在如果我尝试检查例如echo我有echo.exe在我当前的目录中,我发现它是外部命令,但不是内部命令。所以我的问题是如何正确地做到这一点。如何检查该程序是内部程序还是外部程序。谢谢。 这是我的代码:

@echo off
setlocal enabledelayedexpansion
if "%1"=="" goto help

:start
if not "%1"=="" (
    shift
    if "%1"=="/?" goto help 
    goto :start
)
set arg=%*

for %%a in ("%pathext:;=" "%") do (
    echo %arg%|findstr /E /I %%a >nul
    rem If file was given with extension
    if not ERRORLEVEL 1 goto with_rashr
)

set ext=0
for %%a in ("%pathext:;=" "%") do (
    if EXIST "%CD%\!arg!%%~a" (
        echo This is an external command: %CD%\!arg!%%~a
        set ext=1
        goto :internal
    )
)

for %%G in ("%path:;=" "%") do (
    for %%a in ("%pathext:;=" "%") do (
        if EXIST "%%~G\!arg!%%~a" (
            echo This is an external command: %%~G\!arg!%%~a
            set ext=1
            goto :internal
        )
    )
)
goto :internal

:with_rashr
echo Command with extension was given
if EXIST "%CD%\!arg!" (
    echo This is an external command: %CD%\!arg!
    set ext=1
    goto :internal
)
for %%G in ("%path:;=" "%") do (
    if EXIST "%%~G\!arg!" (
        echo This is an external command: %%~G\!arg!
        set ext=1
        goto :internal
    )
)

:internal
set PATH=
rem set PATH=%PATH%;%CD%
help %arg% >nul 2>&1
rem set error_check=%ERRORLEVEL%
rem echo %error_check%
rem %arg% /?
rem ERRORLEVEL 9009 when a batch attempts to execute a program that is not found.
rem echo %ext%
if ERRORLEVEL 9009 (
    echo We couldn't execute command
    if "%ext%"=="0" (
        echo This is not a command
    )
    endlocal
    goto :EOF
)
if "%ext%"=="1" (
    if ERRORLEVEL 0 (
        echo This is also an internal command
    )
    endlocal
    goto :EOF
)
echo This is internal command

endlocal
goto :EOF

:help
echo Like which
echo Shows if this command external or internal

好问题,而且解决起来出奇的困难。

我以为我有一个很好的工作版本http://ss64.org/viewtopic.php?pid=5752#p5752 http://ss64.org/viewtopic.php?pid=5752#p5752,其中我回应了另一个人试图做基本相同的事情。但是在读完你的问题后,我意识到我的旧“解决方案”也遇到了同样的问题 - 如果路径中的某处碰巧存在具有相同根名称的 exe,它会错误地将内部命令报告为外部命令。

我首先检查是否可以找到外部命令,如果没有,那么我假设 HELP 知道的任何命令都是内部命令。

我想我现在有一个工作版本。

我首先使用与您尝试过的类似技术检查该命令是否是内部命令。我添加了一些曲折。

  • 我依赖于 %temp% 文件夹中的一个空文件夹(如果它不存在,我会创建它)
  • 我担心命令注入,因此在进行内部测试之前我会验证命令是否只包含字母。
  • The (CALL )命令是清除错误级别的快速方法

据我所知,如果给定参数,每个内部命令都会打印出帮助信息/?。如果该命令不是内部命令,则它将无法执行并将 ERRORLEVEL 设置为 9009,因为 PATH 为空且当前目录为空。

::WHICH  CommandName  [ReturnVar]
::
::  Determines the full path of the file that would execute if
::  CommandName were executed.
::
::  The result is stored in variable ReturnVar, or else it is
::  echoed to stdout if ReturnVar is not specified.
::
::  If no file is found, then an error message is echoed to stderr.
::
::  The ERRORLEVEL is set to one of the following values
::    0 - Success: A matching file was found
::    1 - CommandName is an internal command
::    2 - No file was found and CommandName is not an internal command
::    3 - Improper syntax - no CommandName specified
::
@echo off
setlocal disableDelayedExpansion

set "file=%~1"
setlocal enableDelayedExpansion

if not defined file (
  >&2 echo Syntax error: No CommandName specified
  exit /b 3
)


:: test for internal command
echo(!file!|findstr /i "[^abcdefghijklmnopqrstuvwxyz]" >nul || (
  set "empty=!temp!\emptyFolder"
  md "!empty!" 2>nul
  del /q "!empty!\*" 2>nul >nul
  setlocal
  pushd "!empty!"
  set path=
  (call )
  !file! /? >nul 2>nul
  if not errorlevel 9009 (
    >&2 echo "!file!" is an internal command
    popd
    exit /b 1
  )
  popd
  endlocal
)


:: test for external command
set "noExt="
if "%~x1" neq "" if "!PATHEXT:%~x1=!" neq "!PATHEXT!" set noExt="";
set "modpath=.\;!PATH!"
@for %%E in (%noExt%%PATHEXT%) do @for %%F in ("!file!%%~E") do (
  setlocal disableDelayedExpansion
  if not "%%~$modpath:F"=="" if not exist "%%~$modpath:F\" (
    endlocal & endlocal & endlocal
    if "%~2"=="" (echo %%~$modpath:F) else set "%~2=%%~$modpath:F"
    exit /b 0
  )
  endlocal
)
endlocal


>&2 echo "%~1" is not a valid command
exit /b 2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在批处理脚本中实施“which”命令 的相关文章

  • 如何修复圆角按钮中边框和背景之间的空白?

    我为我的 WPF 应用程序创建了一个简单的按钮模板
  • Qt GUI 应用程序中的控制台输出?

    我有一个在 Windows 上运行的 Qt GUI 应用程序 它允许传递命令行选项 在某些情况下我想向控制台输出一条消息 然后退出 例如 int main int argc char argv QApplication a argc arg
  • 如何在拥有句柄时检查给定进程是否正在运行

    我在用ShellExecuteEx启动应用程序 成功开始阅读后TShellExecuteInfo hProcess获取已启动进程的句柄 我想定期检查我的应用程序启动的进程是否仍在运行 两个或多个同名进程可以同时运行 我想确保我的应用程序正在
  • 如何为 Windows toast 注册协议?

    如何注册 Windows toast 协议 样本中来自https blogs msdn microsoft com tiles and toasts 2015 07 02 adaptive and interactive toast not
  • MSysGit 与 Windows 版 Git

    我无法确定MSysGit 和 Windows 版 Git 之间的区别 http msysgit github com 它们有何不同 为什么我会选择其中之一而不是另一个 它们不是同一个东西吗 On http msysgit github co
  • xcodebuild 命令工具,无需安装 Xcode 本身

    我需要在不会进行任何开发的机器上以自动化流程构建 Xcode 项目 我还想节省该机器上的磁盘空间 我以为xcodebuild命令行将是完美的 但要安装该工具 您需要安装 Xcode 本身 有没有办法只安装xcodebuild和其他依赖项 我
  • 使用 Objective-C 进行 Windows 开发

    最近读了一篇关于 Objective C 的文章 我觉得它是一门相当简洁的语言 具有很多很酷的功能 我无意进行任何 iPhone 开发 但是我了解 GCC 能够编译 Objective C 代码 所以我想知道 Objective C 是 W
  • sh / Bash shell 脚本中 !# (bang-pound) 的含义是什么?

    我想了解这个 Scala 脚本是如何工作的 usr bin env bash exec scala 0 object HelloWorld def main args Array String println Hello world arg
  • Docker 警告:无法从守护进程获取默认注册表端点

    在 Windows 10 上 当我调用 docker 命令时 docker pull mongo windowsservercore 我得到以下输出 Warning failed to get default registry endpoi
  • 在 SWI Prolog 中使用 process_create/3 使用命令提示符或 shell 时出错

    在 Windows 7 上 当我在 SWI Prolog 中使用 process create 3 打开 Notepad exe 等应用程序时 记事本将打开 但是 它不适用于使用命令提示符的应用程序 例如 当我尝试打开命令提示符窗口时 使用
  • MSI 安装程序,64 位操作系统,写入 \windows\system32\inetsrv 文件夹

    在 Windows Server 2008 64 位上 我需要一个 msi 安装程序文件来将一些文件写入 windows system32 inetsrv 文件夹 这些文件是一些 XML 架构验证文件 C XmlReaderSettings
  • 开放简历fisherfaces

    我有这个问题 当我使用 vs2010 调试 opencv 2 4 0 facetec demo c 运行时 程序出现此错误 OpenCV错误 未知函数中图像步长错误 矩阵不连续 因此其行数无法更改 文件 src opencv modul e
  • Windows:如何获取所有可见窗口的列表?

    无论如何都要使用相关技术重新标记 我不知道它们是什么 稍后我可能会提出更详细的问题 关于具体细节 但现在我正在尝试掌握 大局 我正在寻找一种方法来枚举 Windows 上的 真实可见窗口 我所说的 真正可见的窗口 就是指 用户所说的 窗口
  • 适用于 Python 的 GitLab CI 共享 Windows 运行器

    我在 GitLab 中有一个 python 项目仓库 我看到 GitLab 共享了可用的测试版 Windows 运行程序 请参阅this https about gitlab com blog 2020 01 21 windows shar
  • 当调用dll函数时,参数对象的成员变量的内存地址发生变化

    类某类 一些成员MemberClass one of the mem 我有一个函数foo SomeClass object 在 dll 中 它是从 exe 调用的 Problem 地址one of the mem 在调度 dll 调用期间发
  • Java 7 默认语言环境

    我刚刚安装了 jre7 我很惊讶地发现我的默认区域设置现在是 en US 对于jre6 它是de CH 与jre7有什么不同 默认区域设置不再是操作系统之一吗 顺便说一句 我使用的是Windows7 谢谢你的回答 编辑 我已经看到了语言环境
  • Apache 子进程已退出,状态为 255

    经过大量的搜索 尝试 修复 等待和哭泣 在我放弃之前 我想为这个错误抓住最后的机会 我们正在奔跑Microsoft Windows Server 2012 Apache 2 4 6 Win64 OpenSSL 1 0 1e PHP 5 5
  • Chromium 中的 MP4 编解码器支持

    我们已将 Chromium 嵌入式框架集成到我们的 Windows 游戏中 以允许我们从应用程序内渲染网页 并且一切正常 除了 MP4 视频 据我所知 由于许可问题 Chromium 不包含此编解码器 但任何人都可以提供有关我们如何添加支持
  • 为什么某些安装程序需要在运行程序之前重新启动计算机?

    我对部署桌面应用程序相当陌生 所以这是我第一次为我的软件构建安装程序 目前 我安装软件后第一次运行它时 它崩溃了 之后 它运行良好 我仍在调试此问题 但我注意到在安装后和运行软件之前立即重新启动似乎可以修复此崩溃 某些安装程序要求您在运行软
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K

随机推荐

  • 为什么 Django 1.9 在设置和 URL 中用列表 [] 替换 tuples () ?

    我有点好奇为什么 Django 1 9 在设置 URL 和其他配置文件中用列表 替换 tuples 我刚刚升级到 Django 1 9 并注意到这些变化 它们背后的逻辑是什么 INSTALLED APPS django contrib ad
  • 带 Joda 时间的本地化日期格式,不含年份

    我正在尝试以本地格式显示日期 但没有年份 所以应该是 12 June for UK June 12 for US 用Joda时间可以实现吗 我们尝试过 dd MMMM 模式 但它不起作用 我们已经尝试过了StringFormat longD
  • 使用 lodash 构建 Angular 2 CLI

    导入总是导致错误 找不到模块 lodash import from lodash 角度 cli build js module exports function defaults return new Angular2App default
  • 面对非阻塞I/O如何设计状态机?

    我正在使用 Qt 框架 该框架默认具有非阻塞 I O 来开发一个应用程序 该应用程序可以浏览多个网页 在线商店 并在这些页面上执行不同的操作 我将特定网页 映射 到状态机 我用它来浏览该页面 该状态机具有以下转换 Connect LogIn
  • 使用主构造函数继承类

    我有一个父类如下 interface ITask open class Task val targetServer Server ITask 然后有一个子级继承它并覆盖主构造函数 如下所示 data class FileTask val s
  • 使滚动条在 UIScrollView 上始终可见?

    我需要使滚动条在 viewDidLoad 上始终可见 以便用户可以了解有内容可以滚动 我做了以下事情 myscrollView flashScrollIndicators 但是滚动条只会在 viewDidLoad 之后出现一段时间 然后再次
  • node.js fs - “向后”流文件 - 从下到上

    使用 Node js 将文件从文件系统流式传输到 Node js 但从下到上向后读取它的最佳方法是什么 我有一个大文件 如果我只想要最后 10 行 从顶部读取似乎没有多大意义 这可能吗 现在我有这个可怕的代码 我们使用浏览器执行 GET 请
  • NuGet - 找不到“添加库包引用...”

    我正在使用安装了 MVC3 的 Visual Studio 2010 SP1 由于我正在学习 NuGet 基础知识 因此我正在阅读本教程http maleevdimka com post NuGet Part 1 aspx http mal
  • Nativecript Fontawesome 5 iPhone 无法工作

    我正在尝试让 Font Awesome 5 在 Android 上运行 但它不起作用 使用https github com NathanWalker nativescript ngx fonticon https github com Na
  • ListView ArrayAdapter,将子项隐藏在 Row 中?

    我觉得有点愚蠢 因为我找不到这个问题的答案 这让我觉得我实际上是在问wrong问题 然而 这里 我有一个列表视图和一个在 xml 中定义的 listviewitem 有几个字段 没有什么特别的 全部设置为可见 然后 我使用自定义 Array
  • 使用 GDB 调试模板

    My gdb是 GNU gdb Red Hat Linux 6 3 0 0 1 162 el4rh 我无法调试模板 如何使用此调试器调试模板 如果您的问题只是在代码中放置断点 这是一个小片段 例如 main cpp include
  • 32/64 位的 MSBuild 和 $(ProgramFiles) 问题

    我编写了一个自定义 MSBuild 任务 它调用SubWCRev exe 一个可执行文件 通常 驻留在C Program Files TortoiseSVN bin 无论是 32 位还是 64 位 因为 TortoiseSVN 提供这两个版
  • 隐藏地图注释而不删除它们

    使用 MKMapView 我加载了一堆注释 并且我希望能够过滤使用分段控件显示的注释 我使用带有类型变量的自定义注释 这样我就可以将它们彼此区分开来 但我无法找到一种方法来随意隐藏和显示注释视图的子集 当然可以 试试这个 Objective
  • 在ajax请求中设置$_SESSION

    我有这个 Jquery Ajax 函数可以在网页中登录 url ajax type POST url url data success function jsonResponse var json JSON parse jsonRespon
  • AWS IoT - 通过.Net、REST 和证书访问影子

    为了学习 AWS IoT 我创建了一些 事物 一个策略 我什至能够使用 IoT CLI 来列出事物 or 列表策略 我什至可以通过 CLI 更新影子更新事物通过 CLI 命令 但是一旦我尝试通过 REST GET POST 请求 通过 Ne
  • 如何使用 Homebrew 在 osx macOS Mojave 上安装 Java 8?

    目前 某些应用程序仍然需要 Java 8 例如 Android SDK Android Studio Jenkins 离子 With brew install java the latest版本已安装 但是如何安装Java 8呢 旧的 Or
  • pre 内的代码在 IE8 上排成一行

    我试图从 a 中获取价值textarea并将其放入一个pre tag 它在 chrome 和 mozilla 上工作正常 但在 IE8 上 整个内容保留在一行中pre tag jsbin链接 http jsbin com uwunug 4
  • 如何在dojo中加载一个不是模块的JS文件?

    首先我要说的是 我是一个 javascript 和 dojo 菜鸟 不过 我一直在使用 D O H 框架为我的 js 代码编写一些单元测试 我注意到的一件事是该框架似乎没有办法模拟 XHR 请求 所以我决定使用 sinon 来进行嘲笑 这是
  • Swift 协议专用通用协议

    是否有可能有一个专门针对通用协议的协议 我想要这样的东西 protocol Protocol RawRepresentable typealias RawValue Int 这确实可以编译 但是当我尝试访问init or rawValue从
  • 在批处理脚本中实施“which”命令

    我试图制作一个像这样的脚本which 所以我想检查这个命令是内部命令还是外部命令或两者兼而有之 我尝试执行程序 但是当程序 例如 exe 不正确时 我的程序退出时出现错误 所以我尝试调用help对于这个程序 但现在如果我尝试检查例如echo