代码之家  ›  专栏  ›  技术社区  ›  Regda

批量-将ECHOed SET定义行重定向到文件将显示该行,而不是将其写入文件

  •  1
  • Regda  · 技术社区  · 9 年前

    我写了以下内容:

    @ECHO OFF
    
    SET v1old=4
    SET v2old=0
    SET v3old=7453
    SET v1new=83
    SET v2new=645
    SET v3new=2
    SET bug=SET
    
    ECHO @ECHO OFF ^& SETLOCAL>>newupdate.bat
    ECHO REM .>>newupdate.bat
    ECHO REM version von dolphin>>newupdate.bat
    ECHO %bug% v1old=%v1new%>>newupdate.bat
    ECHO %bug% v2old=%v2new%>>newupdate.bat
    ECHO %bug% v3old=%v3new%>>newupdate.bat
    ECHO %bug% bug=%bug%
    
    PAUSE
    EXIT
    

    以下行将显示在控制台中,而不是写入bat文件中:

    ECHO %bug% v3old=%v3new%>>newupdate.bat
    

    变量v3new存储从0-9开始的值,如果我让它们存储字符、符号或大于1位数的值,它将工作。。。

    我希望脚本自己变异,只有第一行会改变。 所以我想把第一行写进一个新文件。。。

    为什么它不起作用,是bug还是我做错了什么?

    4 回复  |  直到 9 年前
        1
  •  2
  •   Community CDub    7 年前

    解决

    这个 answer 通过 Seth McCauley echo -电子版 set 线

    另一种更通用的解决方案是 回响 在像这样的括号内,因此原始 设置 字符串被重定向而不进行任何修改:

    (ECHO %bug% v3old=%v3new%)>>newupdate.bat
    

    另一种更糟糕的可能性是插入一个 空间 重定向之前 > / >> ; 这将防止该行显示在控制台窗口中,但是 空间 也被重定向(并且,当 newupdate.bat 则它也将被分配给变量值)。


    根本原因

    问题是失败中出现的字符组合 回响 第三行(此处为第三行):

    ECHO %bug% v1old=%v1new%>>newupdate.bat
    ECHO %bug% v2old=%v2new%>>newupdate.bat
    ECHO %bug% v3old=%v3new%>>newupdate.bat
    

    去除 @echo off 暂时从批处理脚本的顶部,您将看到分别向控制台回显的命令行:

    ECHO SET v1old=83 1>>newupdate.bat
    ECHO SET v2old=645 1>>newupdate.bat
    ECHO SET v3old= 2>>newupdate.bat
    

    控制台显示不需要的响应,该响应未写入 新更新.bat 无意中:

    SET v3old=
    

    这是因为字符子字符串 =2>> 在扩展和回显命令中。为什么?

    1. = 用作分隔符,类似 空间 , , , ; .
    2. 由于前面的分隔符 = , 2>> 被视为重定向运算符。
    3. 2 ,因为它是紧挨在前面的一位数 >> ,作为重定向的句柄,其中2表示STDERR(1是STDOUT > / >> ; 0是STRIN,3-9是未定义的)。

    所有这些都意味着STDERR被重定向到 新更新.bat 而不是 回响 -出现在STDOUT(手柄1)的ed行。STDERR在这里不携带数据,因此文件中没有任何内容。
    对于其他行,由于至少违反了上面列出的条件之一,因此不会无意中修改重定向,因此 >> (与 1>> )因此STDOUT被重定向到文件中,STDERR转到控制台,但无论如何都是空的。

    因此,STDOUT针对上述三行携带以下数据:

    SET v1old=83
    SET v2old=645
    

    注意,在没有重定向的情况下,STDOUT和STDERR都默认传递到控制台。

    参考 this resource 对于重定向语法和 this post 有关重定向的详细解释。

    结论

    因为有一个分隔符( 空间 , , , ; , = )后跟变量字符串部分,后跟重定向符号 >> ,当所述中心字符串变为单个十进制数字时,可能会发生意外重定向。

    在这个答案(包括引用的答案)上方提供的所有解决方案都有效,因为重定向标记之间插入了一个字符 >> 以及前面的字符串部分。

        2
  •  1
  •   foxidrive    9 年前

    这里有两种现代的方法,可以在没有尾随空格的情况下回显到文件中:

    注意,第一个重定向只有一个 > 创建或覆盖文件。

    @ECHO OFF
    
    SET v1old=4
    SET v2old=0
    SET v3old=7453
    SET v1new=83
    SET v2new=645
    SET v3new=2
    SET bug=SET
    
     >newupdate.bat ECHO @ECHO OFF ^& SETLOCAL
    >>newupdate.bat ECHO REM .
    >>newupdate.bat ECHO REM version von dolphin
    >>newupdate.bat ECHO %bug% v1old=%v1new%
    >>newupdate.bat ECHO %bug% v2old=%v2new%
    >>newupdate.bat ECHO %bug% v3old=%v3new%
    ECHO %bug% bug=%bug%
    
    PAUSE
    EXIT
    

    这种方法非常有用,但是 ) 需要逃到 ^) 而且

    @ECHO OFF
    
    SET v1old=4
    SET v2old=0
    SET v3old=7453
    SET v1new=83
    SET v2new=645
    SET v3new=2
    SET bug=SET
    
    (
    ECHO @ECHO OFF ^& SETLOCAL
    ECHO REM .
    ECHO REM version von dolphin
    ECHO %bug% v1old=%v1new%
    ECHO %bug% v2old=%v2new%
    ECHO %bug% v3old=%v3new%
    )>newupdate.bat
    ECHO %bug% bug=%bug%
    
    PAUSE
    EXIT
    
        3
  •  0
  •   Seth McCauley    9 年前

    批次 echo 命令在显示某些内容时存在各种问题。在SET语句周围加上双引号将解决您遇到的问题。您可能还想更改第一个文件重定向以使用 > 而不是 >> ,这样每次都会覆盖批处理文件,而不是附加到。以下是更新的代码:

    @ECHO OFF
    SET "v1old=4"
    SET "v2old=0"
    SET "v3old=7453"
    SET "v1new=8"
    SET "v2new=645"
    SET "v3new=2"
    
    ECHO @ECHO OFF ^& SETLOCAL>newupdate.bat
    ECHO REM .>>newupdate.bat
    ECHO REM version von dolphin>>newupdate.bat
    ECHO SET "v1old=%v1new%">>newupdate.bat
    ECHO SET "v2old=%v2new%">>newupdate.bat
    ECHO SET" v3old=%v3new%">>newupdate.bat
    
    PAUSE
    EXIT
    
        4
  •  0
  •   RGuggisberg    9 年前

    这是因为v3new是2。所以您将STDERR定向到newupdate.bat。对您来说,看到这一点的简单方法是暂时注释掉@ECHO OFF,您将看到所讨论的行扩展到

    ECHO SET v3old= 2>>newupdate.bat
    

    @赛斯有很好的建议,但你仍然有问题。在>和newupdate。蝙蝠在每种情况下都能解决问题。