将函数的值返回到批处理脚本中的函数

时间:2018-12-20 14:38:06

标签: windows batch-file cmd scope

这可能是SO,dostips和ss64中几个问题的重复。我所做的研究指出,我需要在函数中寻找 _scope _ 。但是我的解决方案简单明了,但仍然存在问题

  1. SETLOCALENDLOCAL的真正背后是什么
  2. context如何在(goto) 2>nul的批处理脚本中工作
  3. 为什么(goto)用花括号包裹(在dostips中解释)

这是我到目前为止编写的用于将文件从一个地方复制到另一个地方的代码。 我的目标是:

  • 研究批处理脚本的scopecontext
  • 代码重用
    @echo off
    setlocal EnableDelayedExpansion
    goto :main

:main
    setlocal
    set _app=test
    set _base=C:/wamp64/www
    set _destination=!_base!/test
    set _source=%~dp0%/build
    set /A _flag=0

    echo *********************************************
    echo    Deploying in %~1 mode: %TIME%
    echo        Deploy path: !^_destination!
    echo *********************************************

    call :check !_base!, !_app!, _flag
    if !_flag!==0 (
        call :create !_base!, !_app!
    )
    xcopy "!_source!" "!_destination!" /D /C
    exit /b 0
    endlocal

:setbase 
    echo ::::: setting up base :::::
    chdir /D C:

    rem the base dir for app to exists=> %1
    chdir %~1 
    exit /b 0

:check 
    echo ::::: checking for local web server destination :::::
    call :setbase %~1

    set %~3= dir /p|find /C "%~2"
    exit /b 0

:create 
    echo ::::: creating the app folders :::::

    rem setting the base to create app folder %1
    call :setbase %~1
    mkdir %~2
    exit /b 0

endlocal

这是我启动deploy.bat

时得到的输出
*********************************************
   Deploying in production mode: 19:28:53.13
       Deploy path: C:/wamp64/www/test
*********************************************
::::: checking for local web server destination :::::
::::: setting up base :::::
0
::::: creating the app folders :::::
::::: setting up base :::::
A subdirectory or file test already exists.

似乎像If !_flag! == 0,它正在检查app文件夹是否在服务器根目录中并且根本不起作用。当我学会了将参数传递给其他功能的方法时;我认为它通过了类似pointer的引用,但看起来与scope紧密相关。 那么代码中发生了什么。

1 个答案:

答案 0 :(得分:2)

检查文件/目录是否存在

您用来验证目录(?)存在的代码是

set %~3= dir /p|find /C "%~2"

我认为这并没有达到您的预期。 SET /P通常这样使用,以便将命令的输出通过管道传递到环境变量中。 (但是,您将/P赋予dir,这会分页输出-可能不是您想要的结果。)但是,您所执行的命令不会这样做。我猜想这是将var设置为(字面意义上的)“ dir / p”,然后通过find-count用管道传输它。 find.exe /C的结果永远不会使其返回envvar。输出线“ 0”是通过find.exe /C进行管道输送(无)的结果。

我提出了一个更简单的存在测试:

IF EXIST "%~2" (SET /A %~3=1) ELSE (SET /A %~3=0)

该测试在我的Win10计算机上有效。

我发现IF EXIST的工作方式有些许差异。如果您不想使用它,可以使用FOR循环来实现。

FOR /F "tokens=*" %%e IN ('DIR /B') DO IF "%%~e"=="%~2" SET /A %~3=1

如果要在FOR命令中使用管道,则必须对其进行转义。

FOR /F "tokens=*" %%e IN ('DIR /B ^| find /C "%~2"') DO SET /A %~3=%%~e

这三种方法都对我有用。

SETLOCAL

除了内置的帮助(SETLOCAL /?)之外,我没有关于cmd语法的官方参考指南

我的经验是,它将所有envvar和工作目录推送到一个“堆栈”上,并将其推送到相应的ENDLOCALEXIT(尽管在脚本中,您几乎总是 想要使用EXIT /B)将使环境脱离该“堆栈”。实际上,这意味着您在SETLOCAL中进行的envvar / CWD更改将只是临时的。