无法在Windows批处理文件的if语句中获取变量值

时间:2013-04-02 13:50:36

标签: batch-file

我正在尝试编写一个简单的批处理文件来控制对计算机的访问(使用关机),因此计算机打开时每30分钟一次,计算机关闭时必须至少有30分钟。该文件将被置于自动启动状态。该算法如下所示:

Get from the file time when the computer was last closed (LASTCLOSETIME)
calculate BREAKUNTIL as LASTCLOSETIME + 30 minutes
if CURRENTTIME < BREAKUNTIL {
    then shutdown now
} else {
    shutdown in 30 minutes
    save to the file CURRENTTIME + 30 minutes
}

如果文件不存在,我没有处理第一次运行中发生的情况,但现在不存在问题 - 文件存在且包含有效数据。

我的代码:

::echo off

FOR /F "DELIMS=" %%G IN ('TIME /T') DO SET CURRENTTIME=%%G
echo %CURRENTTIME%

set /A CURRENTTIME = %CURRENTTIME:~0,2%*60 + %CURRENTTIME:~3,2%
echo %CURRENTTIME%

set /P LASTCLOSETIME=<lastclose.txt

set /A BREAKUNTIL = %LASTCLOSETIME% + 30
set /A BREAKUNTIL = %BREAKUNTIL% %% 1440

echo CURRENTTIME: %CURRENTTIME%
echo LASTCLOSETIME: %LASTCLOSETIME%
echo BREAKUNTIL: %BREAKUNTIL%

if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
    shutdown -s -t 30
) else (
    shutdown -s -t 1800

    set CLOSETIME = %CURRENTTIME%
    echo CLOSETIME: %CLOSETIME%
    set /A CLOSETIME = %CLOSETIME% + 30
    set /A CLOSETIME = %CLOSETIME% %% 1440

    echo %CLOSETIME%
    echo %CLOSETIME% > lastclose.txt
)

PAUSE

问题出在我设置CLOSETIME的地方。它成功获得CURRENTTIME的值,我可以看到,例如控制台中的"set CLOSETIME = 886"但下一行根本不打印此时间,就好像未设置变量一样。它与if语句有关吗?我尝试过使用标签和goto语句,但结果是一样的。

1 个答案:

答案 0 :(得分:1)

标准DELAYEDEXPANSION问题。

这是一个复合声明:

if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
    shutdown -s -t 30
) else (
    shutdown -s -t 1800

    set CLOSETIME = %CURRENTTIME%
    echo CLOSETIME: %CLOSETIME%
    set /A CLOSETIME = %CLOSETIME% + 30
    set /A CLOSETIME = %CLOSETIME% %% 1440

    echo %CLOSETIME%
    echo %CLOSETIME% > lastclose.txt
)

当语句为PARSED时,任何%var%的CURRENT值将被替换, THEN 将执行该语句。在语句执行之前,该值不会分配给closetime,因此该语句被解释为

if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
    shutdown -s -t 30
) else (
    shutdown -s -t 1800

    set CLOSETIME = %CURRENTTIME%
    echo CLOSETIME: 
    set /A CLOSETIME = + 30
    set /A CLOSETIME =  %% 1440

    echo 
    echo  > lastclose.txt
)

最简单的治疗方法是将此序列更改为

if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
    shutdown -s -t 30
    GOTO :EOF
)
shutdown -s -t 1800

set CLOSETIME = %CURRENTTIME%
echo CLOSETIME: %CLOSETIME%
set /A CLOSETIME = %CLOSETIME% + 30
set /A CLOSETIME = %CLOSETIME% %% 1440

echo %CLOSETIME%
echo %CLOSETIME% > lastclose.txt

请注意,冒号为GOTO :EOF的{​​{1}}表示“转到物理文件结尾。”

第二个最简单的是执行

required

在此SETLOCAL ENABLEDELAYEDEXPANSION 语句之前的某个地方(通常直接在IF之后)并将@echo off更改为

IF

注意到当if "%CURRENTTIME%" LSS "%BREAKUNTIL%" ( shutdown -s -t 30 ) else ( shutdown -s -t 1800 set CLOSETIME = %CURRENTTIME% echo CLOSETIME: !CLOSETIME! set /A CLOSETIME = !CLOSETIME! + 30 set /A CLOSETIME = !CLOSETIME! %% 1440 echo !CLOSETIME! echo !CLOSETIME! > lastclose.txt ) 生效时,DELAYEDEXPANSION返回RUNTIME值!var!(即更改时),而var返回PARSE-TIME值{ {1}}(即在执行之前解析语句时的情况。)