提问人:stefan.at.kotlin 提问时间:4/14/2012 更新时间:12/28/2022 访问量:113720
类似于批处理文件中的函数/方法?
Something like a function/method in batch files?
问:
有没有什么东西可以模仿一个方法,比如人们从 Java、C# 等中知道它?我在批处理文件中有 5 行命令,这 5 行在批处理文件中的多个位置使用。我不能使用 goto,因为根据这 5 行创建的 errorlevel,我有不同的操作。我尝试将我的 5 行放在批处理文件中 5lines.bat,但原始批处理文件原始.bat只调用 5lines.bat并且在调用 5lines 后不执行命令.bat ):这就是我的原始.bat的样子:
5lines.bat
echo this gets never called, how to make sure this gets called?
5lines.bat中没有出口或类似的东西!如何确保 5lines.bat 之后的行被调用?
答:
您可以使用 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
评论
goto :eof
与 相同,两者都在调用后返回exit /b
CALL
:myDosFunc
将可重用函数放入单独的批处理文件中肯定会模拟函数。
问题是,您必须使用该命令,以确保在第二个批处理文件完成执行后,控制权返回给调用方。call
call 5lines.bat
echo this will now get called
评论
5lines.bat
5lines.cmd
call 5lines
您可以尝试使用 DOS Batch - Function Tutorial 中列出的示例
或者,您可以将公共行放入从主文件调用的另一个批处理文件中
有关编写可重用批处理文件代码的另一个精彩教程,请参阅 Richie Lawrence 的优秀库。
溶液:
@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 放在每个函数的末尾,以及在函数定义开始之前,在我的示例中,这是:
退出 /B %ERRORLEVEL%
这里有一个“黑客”,可以让你在批处理文件中拥有“匿名”功能:
@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 语句结尾
诀窍是内部使用,然后返回到执行的行。通过双重扩展,将触发 GOTO 帮助消息(带参数),然后继续脚本。但是在完成后,它会返回到 - 这就是为什么需要 if 语句的原因。CALL
GOTO
CALL
%%/?%%
CALL
为了完整起见,您还可以将参数传递给函数:
函数调用
call :myDosFunc 100 "string val"
功能体
:myDosFunc
echo. Got Param#1 %~1
echo. Got Param#2 %~2
goto :eof
我不确定从其他答案中是否很明显,但为了明确起见,我发布了这个答案。我发现其他答案对编写下面的代码很有帮助。
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%
评论
goto :%returnto%
goto :eof
call ...
call
作为 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
下面的代码演示了上述脚本的紧密 Java 等效项。.bat
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);
}
}
下面可能使它看起来像一个函数。
call :myFunc %para1% %para2%
:myFunc <para1> <para2>
echo %1
echo %2
EXIT /B
例
@echo off
echo PROGRAM_NAME:%~nx0 Start
echo.
================================
SET debugMode=%1
call :myFunc1 %debugMode%
call :myFunc2 para1 "para2 hello"
================================
echo PROGRAM_NAME:%~nx0 End & pause>nul
EXIT /B
:: 👇 define the function under below
:myFunc1 <isDebug>
:: So that you can know the %1 means: isDebug.
if "%1" == "1" (
echo debug mode
)
EXIT /B
:myFunc2 <para1> <para2>
:: output: para1
echo %1
:: output: "para2 hello"
echo %2
EXIT /B
上一个:WPF:创建对话框/提示
下一个:了解 Matlab FFT 示例
评论
CALL
a subroutine (:label
) 的部分