如何在不同的.bat文件中调用动态标签

时间:2017-03-22 13:55:15

标签: batch-file environment-variables call

如果我想从bar.bat调用foo.bat中的foo:

::foo.bat
echo.wont be executed
exit /b 1
:foo
echo foo from foo.bat
exit /b 0

::bar.bat
call :foo
exit /b %errorlevel%
:foo
foo.bat
echo.will also not be executed

但是,如果我不知道标签名称但是将其作为参数传递我就会被卡住

::bar.bat
:: calling a dynamic label is no problem
call :%~1
exit /b %errorlevel%
::don't know how to "catch-all" or set context of "current-label"
:%~1
foo.bat

4 个答案:

答案 0 :(得分:1)

您可以使用批量解析器技巧 您无需在foo.bat中执行任何操作

::foo.bat
echo.wont be executed
exit /b 1
:func1
echo foo from foo.bat
exit /b 0

:unknown
echo Hello from %0 Func :unknown
exit /b

您只需要在bar.bat

中添加要foo.bat的任何标签
@echo off
::bar.bat
call :unknown
echo Back from Foo
call :func1
echo Back from Foo
exit /b %errorlevel%

:unknown
:func1
foo.bat
echo NEVER COMES BACK HERE

诀窍是在bar.bat中调用标签然后启动foo.bat 而不用调用它(仅foo.bat)后,加载foo.bat并且最后一个叫做标签的是跳到。

答案 1 :(得分:1)

在解析环境变量或参数引用之前,解析器会逐字搜索标签,因此您无法在标签中使用这些标签。
但是,我想提供一种允许使用动态标签的方法,虽然我不明白它的目的是什么,所以这更像是一种学术答案......

save: function() { this.$validator.validateAll().then(() => { const err = this.$validator.getErrors(); if (err.errors.length > 0) //failed validation else //passed validation }); } 的批处理文件解析器不会缓存批处理文件,它会逐行读取并执行它,或者正确地说出,它会单独读取和执行每个命令行/块。因此,我们可以利用它并让批处理文件在执行期间自行修改,因为修改后的部分超出了当前执行的代码部分。以下脚本实现了:

cmd

基本上,它首先用作为第一个命令行参数提供的字符串替换文字标签字符串(行)@echo off setlocal EnableExtensions DisableDelayedExpansion rem // Check whether a label name has been delivered: if "%~1"=="" ( echo ERROR: No label name specified! 1>&2 exit /B 1 ) rem /* Call sub-routine to replace the literal label string `:%~1` rem within this batch file by the given dynamic label name: */ call :REPLACE_LINE "%~f0" ":%%%%~1" ":%~1" || ( rem /* In case the given label is `:REPLACE_TEXT`, display error rem message, clean up temporary file and quit script: */ >&2 echo ERROR: Label ":%~1" is already defined! 2> nul del "%~f0.tmp" exit /B 1 ) rem // Perform call of the sub-routine with the dynamic label name: call :%~1 rem /* Call sub-routine to replace the given dynamic label name rem within this batch file by the literal label string `:%~1`: */ call :REPLACE_LINE "%~f0" ":%~1" ":%%%%~1" endlocal exit /B :REPLACE_LINE val_file_path val_line_LOLD val_line_LNEW ::This sub-routine searches a file for a certain line ::case-insensitively and replaces it by another line. ::ARGUMENTS: :: val_file_path path to the file; :: val_line_LOLD line to search for; :: val_line_LNEW line to replace the found line; setlocal DisableDelayedExpansion rem // Store provided arguments: set "FILE=%~1" & rem // (path of the file to replace lines) set "LOLD=%~2" & rem // (line string to search for) set "LNEW=%~3" & rem // (line string to replace the found line) set "LLOC=%~0" & rem // (label of this sub-routine) rem // Write output to temporary file: > "%FILE%.tmp" ( rem /* Read the file line by line; precede each line by a rem line number and `:`, so empty lines do not appear as rem empty to `for /F`, as this would ignore them: */ for /F "delims=" %%L in ('findstr /N "^" "%FILE%"') do ( rem // Store current line with the line number prefix: set "LINE=%%L" setlocal EnableDelayedExpansion rem // Check current line against search string: if /I "!LINE:*:=!"=="!LOLD!" ( rem // Current line equals search string, so replace: echo(!LNEW! ) else if /I not "!LNEW!"=="!LLOC!" ( rem // Current line is different, so keep it: echo(!LINE:*:=! ) else ( rem /* Current line equals label of this sub-routine, rem so terminate this and return with error: */ exit /B 1 ) endlocal ) ) rem /* Searching and replacement finished, so move temporary file rem onto original one, thus overwriting it: */ > nul move /Y "%FILE%.tmp" "%FILE%" endlocal exit /B :%~1 ::This is the sub-routine with the dynamic label. ::Note that it must be placed after all the other code! echo Sub-routine. exit /B ,然后它按:%~1调用该部分,最后,它恢复原始文件文字标签字符串。替换由子例程call :%~1管理。

答案 2 :(得分:0)

foo.bat(二级):

@echo off
echo   this is foo.bat
REM check, if the label is defined in this script:
findstr /xi "%~1" %~f0 >nul 2>&1 || goto :error
goto %~1

:foo
echo     reached foo.bat, label :foo
exit /b 0

:error
echo       wrong or missing label: "%~1"
exit /b 1

bar.bat(主要)

@echo off
echo this is bar.bat
call foo.bat :foo
echo back to bar.bat - %errorlevel%
call foo.bat :foe
echo back to bar.bat - %errorlevel%
call foo.bat
echo back to bar.bat - %errorlevel%
exit /b

答案 3 :(得分:0)

由于aschipfl已经正确声明您无法拥有动态标签,但您可以动态调用当前标签,但是您应该先调用它,然后像Stephan那样调用它,但是在主要批次中。 所以这是Stephans和jebs批次的组合。

:: bar.bat
@echo off
REM check, if the label is defined in this script:
If "%~1" neq "" findstr /xi "%~1" %~f0 >nul 2>&1||goto :error&&Call :%~1
call :Func1
echo Back from Foo
call :func2
echo Back from Foo
exit /b %errorlevel%

:error
echo       wrong or missing label: "%~1"
exit /b 1

:func1
:func2
foo.bat
echo NEVER COMES BACK HERE
:: foo.bat 
@Goto :Eof

:func1
echo     reached foo.bat, label :func1
exit /b 0

:func2
echo     reached foo.bat, label :func2
exit /b 0

示例输出:

> bar
    reached foo.bat, label :func1
Back from Foo
    reached foo.bat, label :func2
Back from Foo

> bar fx
      wrong or missing label: "fx"