如何将批处理文件中的所有函数打包为单独的文件?

Per*_*est 11 windows command-line batch-file

我的问题与这个问题有关.我有几堆需要从批处理文件执行的操作,我想将它们建模为函数并从主序列调用.从上面的问题来看,很明显我可以用调用语法来做到这一点

call:myDosFunc
Run Code Online (Sandbox Code Playgroud)

我的问题是,我可以将所有这些函数放在一个单独的批处理文件(functions.bat)中,并以某种方式'包含'在主批处理文件中并调用它们吗?另一种选择是利用调用syntaxt从main.bat调用functions.bat的可能性,但我不确定是否可以使用特定函数调用它而不是执行整个批处理文件.

简而言之,我正在寻找类似于C编程世界的东西,其中我的函数驻留在DLL中,主程序只包含高级逻辑并从DLL调用函数.

小智 8

我认为批处理文件开头的路由功能并不那么难看.你可以在" libbatch.cmd " 的开头使用这样的东西

    call:%*
    exit/b

:func1
    [do something]
    exit/b

:func2
    [do something else]
    exit/b
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用以下命令从另一批中调用func2:

call libbatch.cmd func2 params1 param2 ... paramN
Run Code Online (Sandbox Code Playgroud)

这也保留了由func2"抛出"的错误级别(退出/ b移交当前的错误级别).使用第二个调用而不是goto,确保"%1"=="param1"而不是func2.如果标签不存在,调用将不会终止批处理文件,它只是将errorlevel设置为1并将错误消息放入2(错误输出),可以将其重定向到nul.

说明:%*包含所有参数,因此在示例中第一行转换为:

call:func2 params1 param2 ... paramN
Run Code Online (Sandbox Code Playgroud)

  • 使用 GOTO 比使用 CALL 更好,因为 CALL 可能会损坏参数:`%` 字符会丢失,并且调用者必须将其加倍以进行补偿。引用的“^”字符通过 CALL 被加倍。“^”加倍是一个令人讨厌的问题。我不知道有什么好的解决方案。 (2认同)

dbe*_*ham 7

这是一个如何完成的简单示例.

调用函数脚本,函数名称作为第一个参数,函数参数作为arg2,arg3,...

假设它被正确调用,脚本会移动参数并执行GOTO到原始arg1.然后该函数的参数以新的arg1开头.这意味着您可以使用已编写的例程并将其放入实用程序中,而无需担心调整参数编号.

如果未提供函数参数,或者函数参数与脚本中的有效标签不匹配,则脚本会出错.

@echo off
if "%~1" neq "" (
  2>nul >nul findstr /rc:"^ *:%~1\>" "%~f0" && (
    shift /1
    goto %1
  ) || (
    >&2 echo ERROR: routine %~1 not found
  )
) else >&2 echo ERROR: missing routine
exit /b

:test1
echo executing :test1
echo arg1 = %1
exit /b

:test2
echo executing :test2
echo arg1 = %1
echo arg2 = %2
exit /b

:test3
echo executing :test3
echo arg1 = %1
echo arg2 = %2
echo arg3 = %3
exit /b
Run Code Online (Sandbox Code Playgroud)

我更喜欢上面使用的GOTO方法.另一个选择是使用CALL,正如Thomas在他的回答中所做的那样.

有关使用CALL技术的有用批处理函数库的工作示例,请参阅CHARLIB.BAT,这是一个用于处理批处理文件中的字符和字符串的例程库.此处提供显示库开发的线程

我几年前写过CharLib.bat.如果我今天写它,我可能会使用GOTO而不是CALL.

引入CALL的问题在于,在将字符串文字作为参数传递时会产生问题.额外的CALL意味着包含的字符串文字%必须使百分比加倍一个额外的时间.它也意味着不带引号的毒药字符&,|需要额外的时间逃脱.调用者可以解决这两个问题.但真正的问题是,每个CALL都会引用引用的插入符号:"^"变为"^^".没有一种解决插入符号倍增问题的好方法.

额外CALL的问题不会影响CharLib.bat,因为字符串值是通过引用(变量名称)传递的,而不是字符串文字.

使用带有SHIFT/1的GOTO的唯一缺点是你不能%0用来获取当前正在执行的例程的名称.我可以在没有/ 1的情况下使用SHIFT,但是您将无法%~f0在例程中使用获取执行批处理文件的完整路径.