set 语句在我的批处理文件中似乎不起作用 [英] set statements don't appear to work in my batch file

查看:37
本文介绍了set 语句在我的批处理文件中似乎不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里找到了对我的问题的解释

I've found what appears to be an explanation of my problem here

DOS批处理:为什么我的设置命令导致没有存储任何内容?

但我真的不明白解释.

这是我的脚本...

for /R /d  %%f in (ProductDatabaseSQLProjectModelScripts*) DO (

REM echo %%f
SET !LOAD_FILE_FILTER= %%f*.sql
echo 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 ]
)

)

回声总是打印 file: *.sql 并且我通过这个 var 的脚本总是抱怨 LOAD_FILE_FILTER 是空的.

The echo always prints file: *.sql and the script I pass this var to always complains LOAD_FILE_FILTER is empty.

我已尝试按照文章中的建议添加 setlocal EnableDelayedExpansion,但并没有解决问题.echo file: %!LOAD_FILE_FILTER% 总是打印我正在运行的目录中的最后一个子目录.echo %%f 总是打印正确的值.

I have tried adding setlocal EnableDelayedExpansion as suggested in the article but it doesn't solve the problem. The echo file: %!LOAD_FILE_FILTER% always prints the last subdirectory in the directory I'm running from. The echo %%f always prints the correct value.

'!' 是什么意思在变量 do for/to me 后面?

What does the '!' behind the variable do for/to me?

顺便说一句,有人可以向我解释一下

On a side note, could someone explain to me the difference between

设置!VAR和设置VAR

SET !VAR and SET VAR

%VAR&&!VAR&!VAR!%%VAR

%VAR& &!VAR& !VAR! %%VAR

推荐答案

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

We are going to start with a simple case

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

阅读代码,它删除变量的内容,为其分配一个新值并回显它.

Reading the code, it removes the content of the variable, assigns it a new value and echoes it.

让我们稍微改变一下,连接最后两个命令

Let's change it a bit concatenating the last two commands

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

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

"Same" code, but in this case the output to console will not show the value in the variable.

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

Why? In batch files, lines to execute are parsed and then executed. During the parse phase, every variable read operation (where you retrieve the value of the variable) is replaced with the value stored inside the variable at parse time. Once this is done, the resulting command is executed. So, in the previous sample when the second line is parsed, it is converted to

set "var=test" & echo 

现在,该行没有读取操作,也没有要回显的值,因为当读取该行时,变量没有保存任何值(执行该行时将对其进行赋值),因此读取操作已什么都没有取代.此时,代码被执行并且感知的行为是 set 命令失败,因为我们没有得到明显"的值回显到控制台.

now, there are no read operations on the line and no value to echo, as when the line was readed the variable didn't hold any value (it will be assigned when the line is executed) so the read operation has been replaced with nothing. At this point, the code is executed and the perceived behaviour is that the set command failed as we don't get the "obvious" value echoed to console.

这种行为也存在于块中.块是括在括号中的一组行(通常是 forif 结构),并且由解析器处理,就好像块中的所有行都只有一行串联命令.读取完整块,删除所有变量读取操作并替换为变量内部的值,然后执行内部没有变量引用的完整块.

This behaviour is also found in blocks. A block is a set of lines enclosed in parenthesis (usually for and if constructs) and are handled by the parser as if all the lines in the block are only one line with concatenated commands. The full block is readed, all variable read operations removed and replaced with the value inside the variables, and then the full block, with no variable references inside is executed.

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

At execution time there are no read operation on variables inside the block, only its initial values, so, any value assigned to a variable inside the block can not be retrieved inside the same block, as there isn't any read operation.

所以,在这段代码中

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

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

after the first set is executed, the block (the if command and all the code enclosed in its parenthesis) will be parsed and converted into

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

显示错误"值.

通常的处理方式是使用延迟扩展.它将允许您在需要时更改将变量从 %var% 读取到 !var! 的语法,向解析器指示读取操作不得在解析时移除,但延迟到命令执行.

The usual way to deal with it is to use delayed expansion. It will allow you to change, where needed, the syntax to read the variable from %var% into !var!, indicating to the parser that the read operation must not be removed at parse time, but delayed until the command is executed.

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

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

The now third line is converted at parse time to

set "var=test" & echo !var!

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

yes, the variable reference is not removed. The read operation is delayed until the echo command will be executed, when the value of the variable has been changed.

所以

%var% 是一个变量引用,在解析时会被替换

%var% is a variable reference that will be replaced at parse time

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

!var! is a variable reference that will be replaced at execution time

%xx 单个字符通常是一个 for 可替换参数,一个保存当前被交互元素的变量.就其本身的性质而言,将在执行时进行扩展.在命令行中使用带有单个百分号的语法.在批处理文件中,百分号需要转义,引用可替换参数的语法是 %%x

%x with x a single character is usually a for replaceable parameter, a variable that will hold the current element being interated. By its own nature, will be expanded at execution time. The syntax with a single percent sign is used at command line. Inside batch files the percent sign need to be escaped and the syntax to refer to the replaceable parameters is %%x

这篇关于set 语句在我的批处理文件中似乎不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆