【问题标题】:Why is my if statement within a function causing an error in batch?为什么我在函数中的 if 语句会导致批处理错误?
【发布时间】:2016-06-14 13:26:26
【问题描述】:

我正在编写一个批处理安装脚本,我试图让这个函数只有在某个变量等于 1 时才运行。每当调用这个函数时,我都会遵循一个正常的语法命令(“命令的语法不正确”)通过在下一行 "C:\Windows\System32> 中断>" 代码如下:

:updateStatus
IF %uploadInfo% EQU 1 (

    REM finds IP
    set ip_address_string="IP Address"
    set ip_address_string="IPv4 Address"
    for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
        SET ip=%%f
        REM  goto :eof  
    )

    REM Removes spaces from IP
    SETLOCAL ENABLEDELAYEDEXPANSION
    for /f "tokens=* delims= " %%a in ("%ip%") do set ip=%%a
    for /l %%a in (1,1,100) do if "!ip:~-1!"==" " set ip=!ip:~0,-1!
    REM echo IP Adress: %ip%

    SET txtLoc=C:\CadVersionInfo\%ip%.txt
    SETLOCAL  DISABLEDELAYEDEXPANSION

    REM SETs time
    For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%a/%%b/%%c)
    For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a:%%b)

    REM writes info
    if not exist C:\CadVersionInfo\ (mkdir C:\CadVersionInfo\)


    if exist "%txtLoc%" (
        del "%txtLoc%"
    )


    break>%txtLoc%


    @echo %trunk%.%build% >>"%txtLoc%"
    @echo %TA%>>"%txtLoc%"
    @echo %mdbname%>>"%txtLoc%"
    REM ~1 is status
    @echo %~1>>"%txtLoc%"
    @echo %mytime% %mydate%>>"%txtLoc%"

    @echo %notes%>>"%txtLoc%"

    REM Sets location on server to store data
    SET txtLocRemote=\\cd-ptt\CAD Downloads\Webserver\servers\*
    xcopy %txtLoc% "%txtLocRemote%" /q /y
 )
goto:eof

【问题讨论】:

  • 您需要启用和使用delayed expansion,因为您在单行/代码块中修改和读取变量值(注意IF %uploadInfo% EQU 1 ( ... ) 被视为单个命令行).. .
  • 只有前 10 行受到 IF %uploadInfo% EQU 1 测试的影响。如果uploadinfo不等于1,IP地址是否已经设置
  • 不,@foxidrive,结尾的) 在脚本的最底部goto:eof 之前;第10行的)属于上面的for /f...
  • @aschipfl 确实如此!谢谢。您对delayed expansion 的建议是正确的,因为变量是在括号内设置的。 Wes Larson 的建议也是一个很好的解决方案。

标签: batch-file


【解决方案1】:

与其尝试使用delayedexpansion 处理所有变量,倒转if 语句并只使用goto 可能更简单,如下所示:

:updateStatus
IF NOT %uploadInfo% EQU 1 goto end

{do stuff}

:end

【讨论】:

    【解决方案2】:

    另一种解决方案是将变量设置在循环之外,并且只在需要时处理循环。

    我已经多次编辑这篇文章,最后使用了 Wes 的解决方案,在这里添加这个只是为了说明实现部分代码的一些不同方法。

    IP 变量中的空格以更简单的方式删除。

    改变了对文件的重定向——使用这种方法可以避免尾随空格。

    SET "txtLocRemote=\\cd-ptt\CAD Downloads\Webserver\servers\*" 中的 * 不是 xcopy 的合法语法,需要修改。

    在这个代码块中,两行被替换了,2>nul 只是在控制台中隐藏了不相关的文本。它会一直尝试创建文件夹并删除文件,如果文件夹已经存在或文件不存在,则不会造成任何损坏。

    if not exist C:\CadVersionInfo\ (mkdir C:\CadVersionInfo\)
    break>"%txtLoc%"
    

    这是您编辑后的代码:

    :updateStatus
    
    IF %uploadInfo% NEQ 1 goto :EOF
    
        REM finds IP
        set ip_address_string="IP Address"
        set ip_address_string="IPv4 Address"
        for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
            SET ip=%%f
            REM  goto :eof  
        )
    
        REM Removes spaces from IP
            SET "ip=%ip: =%"
        REM echo IP Adress: %ip%
    
        SET "txtLoc=C:\CadVersionInfo\%ip%.txt"
    
        REM Sets location on server to store data
        SET "txtLocRemote=\\cd-ptt\CAD Downloads\Webserver\servers\*"
    
        REM SETs time
        For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%a/%%b/%%c)
        For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a:%%b)
    
    
        REM writes info
    
        mkdir "C:\CadVersionInfo" 2>nul
        del "%txtLoc%" 2>nul
    
    
        >>"%txtLoc%" @echo %trunk%.%build%
        >>"%txtLoc%" @echo %TA%
        >>"%txtLoc%" @echo %mdbname%
        REM ~1 is status
        >>"%txtLoc%" @echo %~1
        >>"%txtLoc%" @echo %mytime% %mydate%
    
        >>"%txtLoc%" @echo %notes%
    
        xcopy "%txtLoc%" "%txtLocRemote%" /q /y
    
    goto:eof
    

    【讨论】:

    • 还有多余的行set ip_address_string="IP Address"。该变量会在下一行立即被覆盖。这看起来可能是在尝试与旧 Windows 版本兼容,但实际上并没有做任何事情。
    • 感谢所有这些优化提示
    猜你喜欢
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多