你如何模仿普通DOS批处理文件中的函数?

时间:2013-12-04 16:37:00

标签: windows batch-file cmd dos

这个问题基本上是关于如何在MS-DOS / Windows命令提示符(减去扩展名)中模拟文件本身的批处理文件中的功能。在命令提示符中,使用扩展名,您只需先在批处理文件的开头调用setlocal enableextensions,然后使用call :function params调用该函数,就像在大多数其他语言中一样调用它(例如function(params))。由于缺少Windows XP中引入的命令提示符扩展,在DOS等(FreeDOS等)中并不容易。

4 个答案:

答案 0 :(得分:4)

如果您正在进行恐龙时代的编程,您应该始终考虑恐龙时代的解决方案。 : - )

rem call the "hello world" function
set return=line101
goto helloworld
:line101

rem now call it again
set return=line102
goto helloworld
:line102

rem ok, I'm done
goto :eof

:helloworld
echo Hello, world!
goto %return%

:eof
rem the end

答案 1 :(得分:1)

我有理由相信你可以在那些早期版本中调用辅助批处理文件,所以你要编写一个像 STRING2.BAT

这样的文件
@echo off
set %1=%2%3

并通过

调用它
call string2 longstring,abcd,%wxyz%
echo concatenated string=%longstring%

(授予,这不是连接两个字符串的理想方式,它只是作为演示)

当然,批量调用本身并使用像::这样的固定参数值来修改 thisbatch.bat 的行为是一种常见的技术,但在以后的日子里却是如此将所有代码保存在一个批处理文件中,您将永远在批处理之间复制代码片段并创建维护噩梦。另一种方法是创建一个单独的 cleverfunction.bat 文件,但是需要创建一个单独的文件,以及需要它的位置,这是一个新的噩梦。

在你们这些必须用勺子给我一种解决方案的日子里,这种技术已不再可行。

答案 2 :(得分:0)

解决方案似乎很难找到,但它实际上比看起来更简单。基本上,这种实现会导致批处理文件以递归方式调用自身,这在以后会更有意义。首先,您需要一种方法来区分函数调用和普通命令行参数。在我的例子中,我将(为了简单起见)使用冒号:来表示该参数是一个函数。这将产生以下代码(仅是命令的一部分):

set fn=%1
if "%fn:0,1%"==":" ...

此代码首先设置一个变量来获取第一个参数并接受它作为函数名称。接下来,我们需要在递归调用中转到该函数,这很简单。

goto %fn%

现在,我们需要一种方法来解决不正确的函数调用,并在错误时终止批处理文件的执行(就像任何具有正确函数调用的语言一样)。此修改将允许捕获此错误,并将立即终止批处理文件。如果你想知道,如果函数不存在,我将语句分成一个变量集。我添加了echo语句,以便于调试。

goto %fn% || set err=t
if defined %err% (
    echo Undefined function: %fn%!
    goto :eof
)

因此,在此之后,您可以像平常一样制作函数,因为goto :eof调用的行为与使用或不使用扩展时的行为相同。这是整个批处理文件的实现(我没有提到所需的移位,就在这里):

@echo off
:: You will not need to enable extensions
:: here.
setlocal
set fn=%1
shift
if "%fn:0,1%"==":" (
    goto %fn% || set err=t
    if defined %err% (
        echo Undefined function: %fn%!
        goto :eof
    )
)

:: Normal commands go here. You can also 
:: include your functions normally as well.

函数调用机制与扩展和必须注意的实现之间的一个小区别是:你必须调用你的函数call %0 :function args而不是call :function args ,就像启用扩展程序一样。如果你不这样做,你肯定会发现很难找到的错误(错误不会让你朝着正确的方向开始)。

如果你想要一点糖,你可以随时set call=call %%0并使用%call% :function args

编辑:我忘记了如何实际调用该函数的细微差别。我把它固定在主体上。

答案 3 :(得分:0)

我使用下面的代码编写:

  

@echo off

     

SETLOCAL

     

设置ldt = nada

     

回声。 %LDT%

     

呼叫:setCurrentTime

     

回声。 %LDT%

     

呼叫:setCurrentTime

     

回声。 %LDT%

     

ENDLOCAL

     。

回波&安培;暂停&安培; GOTO:EOF

     

:: --------------------------------------------- -----------

     

:: - 功能部分从这里开始

     

:: --------------------------------------------- -----------

     

:setCurrentTime

     

rem **** Obtem data e hora corrente:INI ********************************** < / p>      

for / F&#34; usebackq tokens = 1,2 delims ==&#34; %{i} in(wmic os get LocalDateTime /VALUE 2^>NUL)如果&#39;。%% i。&#39; ==&#39; .LocalDateTime。&#39; set ldt = %% j

     

设置ldt =%ldt:~6,2%/%ldt:~4,2%/%ldt:~0.4%%ldt:~8,2%:%ldt:~10,2%: %LDT:〜12,6%

     

rem **** Obtem数据如下:FIM ********************************** < / p>      

:转到:EOF