为了账号安全,请及时绑定邮箱和手机立即绑定

set语句似乎不适用于我的批处理文件

set语句似乎不适用于我的批处理文件

达令说 2019-08-23 10:06:40
set语句似乎不适用于我的批处理文件但我真的不明白这个解释。这是我的剧本......for /R /d  %%f in (\Product\Database\SQL\Project\Model\Scripts\*) DO (REM echo %%fSET !LOAD_FILE_FILTER= %%f\*.sqlecho file: %!LOAD_FILE_FILTER%CALL %!BATCH_FILE% -u %!USER_NAME% -p %!PASSWORD% -s %!SERVER_NAME% -d %!DATABASE_NAME% -f %!LOAD_FILE_FILTER% -o %!LOG_FILE%IF %!EchoErrors%==1 (     ECHO [     TYPE %!LOG_FILE%     ECHO ]))echo始终打印文件:* .sql,我传递此var的脚本总是抱怨LOAD_FILE_FILTER为空。我尝试setlocal EnableDelayedExpansion按照文章中的建议添加,但它没有解决问题。将echo file: %!LOAD_FILE_FILTER%始终打印在我运行的目录中的最后一个子目录。将echo %%f始终打印正确的值。什么是'!' 变量背后为我做什么?另外,有人可以向我解释两者之间的区别SET!VAR和SET VAR%VAR &&!VAR&!VAR!%% VAR
查看完整描述

2 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

我们将从一个简单的案例开始

set "var="set "var=test" echo %var%

读取代码后,它会删除变量的内容,为其赋予一个新值并回显它。

让我们稍微改变最后两个命令

set "var="set "var=test" & echo %var%

“相同”代码,但在这种情况下,输出到控制台不会显示变量中的值。

为什么?在批处理文件中,将解析然后执行要执行的行。在解析阶段,每个变量读取操作(在此处检索变量的值)将替换为在解析时存储在变量内的值。完成此操作后,将执行生成的命令。因此,在解析第二行的前一个示例中,它将转换为

set "var=test" & echo

现在,线路上没有读取操作,没有回显值,因为当线路被加入时,变量没有保存任何值(它将在执行线路时分配),因此读取操作已被替换为空。此时,执行代码并且感知到的行为是set命令失败,因为我们没有得到回显到控制台的“明显”值。

在块中也可以找到此行为。块是括在括号中的一组行(通常forif构造),并由解析器处理,就像块中的所有行只有一行具有连接命令一样。重写完整块,删除所有变量读取操作并用变量内部的值替换,然后执行内部没有变量引用的完整块。

在执行时,对块内的变量没有读操作,只有其初始值,因此,在同一块内不能检索分配给块内变量的任何值,因为没有任何读操作。

所以,在这段代码中

set "test=before"if defined test (
    set "test=after"
    echo %test%)

set执行第一个之后,if将解析块(命令和括号中包含的所有代码)并将其转换为

if defined test (
    set "test=after"
    echo before)

显示“错误”的价值。

处理它的常用方法是使用延迟扩展。它可以让你改变,在需要的地方,语法从读可变%var%!var!,指示该读操作不能在分析时被删除,但推迟到执行该命令的语法分析器。

setlocal enabledelayedexpansionset "var="set "var=test" & echo !var!

现在的第三行在解析时转换为

set "var=test" & echo !var!

是的,不删除变量引用。echo当变量的值已经改变时,读操作被延迟,直到执行命令。

所以

%var% 是一个变量引用,将在分析时替换

!var! 是一个将在执行时替换的变量引用

%xx单个字符通常是一个for可替换的参数,将容纳被interated当前元素的变量。就其本身而言,将在执行时扩展。在命令行中使用带有单个百分号的语法。在批处理文件内部,需要转义百分号,并且引用可替换参数的语法是%%x


查看完整回答
反对 回复 2019-08-23
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

这是一个很好的信息,但我仍然在这里旋转我的车轮。根据这个解释,我希望这可以工作,setlocal EnableDelayedExpansion for /R /d %%f in (Product\Database\SQL\ICWProject\Model\Scripts\*) DO ( SET LOAD_FILE_FILTER=%%f\*.sql echo file: !LOAD_FILE_FILTER! server: %!SERVER_NAME% CALL %!BATCH_FILE% -s %!SERVER_NAME% -d %!DATABASE_NAME% -f !LOAD_FILE_FILTER! -u %!USER_NAME% -p %!PASSWORD% -o %!LOG_FILE% )!LOAD_FILE_FILTER!总是评估我第一次通过循环后的期望

查看完整回答
反对 回复 2019-08-23
  • 2 回答
  • 0 关注
  • 548 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信