像批处理文件中的函数/方法?

时间:2012-04-13 22:37:53

标签: windows command-line batch-file

有没有什么可以像Java,C#等人那样模仿一个方法?我在批处理文件中有5行命令,这5行用于批处理文件中的多个位置。我不能使用goto,因为根据这5行创建的错误级别,我有不同的操作。我尝试将我的5行放在批处理文件5lines.bat中,但原始批处理文件original.bat只调用5lines.bat并且在调用5lines.bat后不执行命令):这就是我的original.bat看起来的样子像:

5lines.bat
echo this gets never called, how to make sure this gets called?

在5lines.bat中没有退出或类似的东西!如何确保调用5lines.bat之后的行?

9 个答案:

答案 0 :(得分:69)

您可以使用call命令:

call:myDosFunc

然后以这种方式定义函数:

:myDosFunc    - here starts the function
echo.  here the myDosFunc function is executing a group of commands
echo.  it could do a lot of things
goto:eof

来源:Batch Functions

答案 1 :(得分:20)

将可重复使用的函数放入单独的批处理文件中肯定可以模拟函数。

需要注意的是,必须使用call命令才能确保在第二个批处理文件完成执行后控制权返回给调用者。

call 5lines.bat
echo this will now get called

答案 2 :(得分:19)

为了完整起见,您还可以将参数传递给函数:

函数调用

call :myDosFunc 100 "string val"

功能正文

:myDosFunc
echo. Got Param#1 %~1
echo. Got Param#2 %~2
goto :eof

答案 3 :(得分:14)

<强>解决方案:

@ECHO OFF     

call:header Start Some Operation

... put your business logic here
... make sure EXIT below is present
... so you don't run into actual functions without the call

call:header Operation Finished Successfully

EXIT /B %ERRORLEVEL%

:: Functions

:header
ECHO ================================================= 
ECHO %*
ECHO ================================================= 
EXIT /B 0

重要的是将EXIT / B放在每个函数的末尾,以及函数定义开始之前,在我的例子中这是:

EXIT / B%ERRORLEVEL%

答案 4 :(得分:5)

您可以尝试使用this page

上列出的示例

或者,您可以将公共行放入另一个您从主要文件

调用的批处理文件中

答案 5 :(得分:2)

这是一个'hack',允许您在批处理文件中使用"anonymous" functions

@echo off
setlocal 
set "anonymous=/?"

:: calling the anonymous function
call :%%anonymous%% a b c 3>&1 >nul

:: here the anonymous function is defined
if "%0" == ":%anonymous%" (
  echo(
  echo Anonymous call:
  echo %%1=%1 %%2=%2 %%3=%3
  exit /b 0
)>&3
::end of the anonymous function

匿名功能块应该放在call语句之后,并且必须以exit语句结束

诀窍是CALL在内部使用GOTO,然后返回执行CALL的行。使用双重扩展触发GOTO帮助消息(使用%%/?%%参数),然后继续脚本。但是在它完成后它返回到CALL - 这就是为什么需要if语句的原因。

答案 6 :(得分:1)

关于编写可重用批处理文件代码的另一个很棒的教程 - 请参阅Richie Lawrence's excellent library

答案 7 :(得分:1)

我不确定其他答案是否显而易见,但为了明确起见,我正在发布此答案。我发现其他答案有助于编写以下代码。

echo what
rem the third param gives info to which label it should comeback to
call :myDosFunc 100 "string val" ComeBack

:ComeBack
echo what what
goto :eof

:myDosFunc
echo. Got Param#1 %~1
echo. Got Param#2 %~2
set returnto=%~3
goto :%returnto%

答案 8 :(得分:0)

来自Java背景,在为.bat脚本创建过程时,我试图结合一些熟悉的约定。

下面的脚本演示了两个过程的定义。

@ECHO OFF
SET firstInstanceVariable="Hello world!"
SET secondInstanceVariable="Good bye world!"
GOTO:MAIN

:firstMethodName
    SETLOCAL ENABLEDELAYEDEXPANSION
        SET firstArgumentPassedIn=%~1
        SET secondArgumentPassedIn=%~2
        
        ECHO %firstInstanceVariable%
        ECHO "The first argument passed in was %firstArgumentPassedIn%"
        ECHO "The second argument passed in was %secondArgumentPassedIn%"
    ENDLOCAL
EXIT /B 0

:secondMethodName
    SETLOCAL ENABLEDELAYEDEXPANSION
        SET firstArgumentPassedIn=%~1
        SET secondArgumentPassedIn=%~2
        
        ECHO %secondInstanceVariable%
        ECHO "The first argument passed in was %firstArgumentPassedIn%"
        ECHO "The second argument passed in was %secondArgumentPassedIn%"
    ENDLOCAL
EXIT /B 0


:MAIN
call:firstMethodName "The Quick Brown" "Fox Jumps Over"
call:secondMethodName "1 2 3 4" 3.14

请注意,必须使用显式GOTO:MAIN来跳过过程定义。 这是因为您在决定阅读程序之前必须跳过该程序。否则,将执行该过程。

下面的代码演示了上述.bat脚本的Java等效语言。

public class MyObject {
    private String firstInstanceVariable = "Hello world!";
    private String secondInstanceVariable = "Good bye world!";
    public void firstMethodName(Object... arguments) {
        String firstArgumentPassedIn = arguments[0].toString();
        String secondArgumentPassedIn = arguments[1].toString();
        System.out.println(firstInstanceVariable);
        System.out.format("The first argument passed in was %s", firstArgumentPassedIn);
        System.out.format("The second argument passed in was %s", secondArgumentPassedIn);
    }

    public void secondMethodName(Object... arguments) {
        String firstArgumentPassedIn = arguments[0].toString();
        String secondArgumentPassedIn = arguments[1].toString();
        System.out.println(secondInstanceVariable);
        System.out.format("The first argument passed in was %s", firstArgumentPassedIn);
        System.out.format("The second argument passed in was %s", secondArgumentPassedIn);
    }

    public static void main(String[] args) {
        MyObject myObject = new MyObject();
        myObject.firstMethodName("The Quick Brown", "Fox Jumps Over");
        myObject.secondMethodName(new Integer[]{1,2,3,4}, 3.14);
    }
}