这可能是SO,dostips和ss64中几个问题的重复。我所做的研究指出,我需要在函数中寻找 _scope _ 。但是我的解决方案简单明了,但仍然存在问题
SETLOCAL
和ENDLOCAL
的真正背后是什么context
如何在(goto) 2>nul
的批处理脚本中工作(goto)
用花括号包裹(在dostips中解释)这是我到目前为止编写的用于将文件从一个地方复制到另一个地方的代码。 我的目标是:
scope
和context
@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
紧密相关。
那么代码中发生了什么。
答案 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 /?
)之外,我没有关于cmd语法的官方参考指南
我的经验是,它将所有envvar和工作目录推送到一个“堆栈”上,并将其推送到相应的ENDLOCAL
或EXIT
(尽管在脚本中,您几乎总是 想要使用EXIT /B
)将使环境脱离该“堆栈”。实际上,这意味着您在SETLOCAL
中进行的envvar / CWD更改将只是临时的。