【问题标题】:Set the value of a variable with the result of a command in a Windows batch file使用 Windows 批处理文件中的命令结果设置变量的值
【发布时间】:2010-10-27 17:35:50
【问题描述】:

Bash 环境中工作时,将变量的值设置为命令的结果,我通常这样做:

var=$(command -args)

其中var 是由命令command -args 设置的变量。然后我可以以$var 的身份访问该变量。

与几乎所有 Unix shell 兼容的更传统的方法是:

set var=`command -args`

也就是说,如何使用 Windows 批处理文件 中的命令结果设置变量的值?我试过了:

set var=command -args

但我发现var 设置为command -args 而不是命令的输出。

【问题讨论】:

    标签: windows batch-file


    【解决方案1】:

    这里有两种方法:

    @echo off
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ;;set "[[=>"#" 2>&1&set/p "&set "]]==<# & del /q # >nul 2>&1" &::
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    :: --examples
    
    ::assigning chcp command output to %code-page% variable
    chcp %[[%code-page%]]%
    echo 1: %code-page%
    
    ::assigning whoami command output to %its-me% variable
    whoami %[[%its-me%]]%
    echo 2: %its-me%
    
    
    ::::::::::::::::::::::::::::::::::::::::::::::::::
    ;;set "{{=for /f "tokens=* delims=" %%# in ('" &::
    ;;set "--=') do @set ""                        &::
    ;;set "}}==%%#""                               &::
    ::::::::::::::::::::::::::::::::::::::::::::::::::
    
    :: --examples
    
    ::assigning ver output to %win-ver% variable
    %{{% ver %--%win-ver%}}%
    echo 3: %win-ver%
    
    
    ::assigning hostname output to %my-host% variable
    %{{% hostname %--%my-host%}}%
    echo 4: %my-host%
    

    脚本的输出:

    1: Active code page: 65001
    2: mypc\user
    3: Microsoft Windows [Version 10.0.19042.1110]
    4: mypc
    

    解释:

    1]&amp;:: 结尾的部分为行尾注释,可以忽略。我把它们只用于宏封闭

    2] 行首的;; 将被忽略,因为; 是批处理脚本的标准分隔符。将它放在那里是为了提醒注释并进一步增强宏定义的分配位置。

    3]使用的技术称为“宏”,它将命令分配给变量,并在调用变量时执行命令。

    4]定义的第一个宏包含两部分:

    set "[[=>"#" 2>&1&set/p "
    

    set "]]==<# & del /q # >nul 2>&1"
    

    &amp; 分隔,这使我可以在一行上定义它们。第一个获取命令的输出并将其重定向到文件#。并添加set/p 以使用set /p technique 开始读取文件。第二个宏以&lt;# 完成set /p 读取,然后删除文件。两个宏之间的文本是变量的名称。类似set /p myVariable=&lt;#

    5] 第二个宏包含三个部分,展开后只是一个for /f 循环。可能可以以更优雅的方式完成。

    【讨论】:

    • 看了很多遍,还是不知道哪一部分只是装饰,哪一部分是实际的命令。我相信你这个例子有效,即使我不明白它的作用。一种方法将如何开始破译这里写的内容?是否有任何类型的 Windows shell 指南,可以在其中查找此处使用的命令?
    • @wvxvw - 我已经添加了解释。
    【解决方案2】:
    Set "dateTime="
    For /F %%A In ('powershell get-date -format "{yyyyMMdd_HHmm}"') Do Set "dateTime=%%A"
    echo %dateTime%
    pause
    

    Official Microsoft docs 用于for 命令

    【讨论】:

      【解决方案3】:

      我看到它完成的唯一方法是你这样做:

      for /f "delims=" %a in ('ver') do @set foobar=%a
      

      ver 是 Windows 的版本命令,它在我的系统上产生:

      Microsoft Windows [Version 6.0.6001]
      

      Source

      【讨论】:

        【解决方案4】:

        要执行 Jesse describes 的操作,您需要从 Windows 批处理文件中编写:

        for /f "delims=" %%a in ('ver') do @set foobar=%%a 
        

        但是,如果您习惯于 Unix 类型的脚本,我建议您在 Windows 系统上使用 Cygwin

        【讨论】:

        • 在命令提示符下使用for /f "delims=" %a in ('ver') do @set foobar=%a。在脚本文件中使用for /f "delims=" %%a in ('ver') do @set foobar=%%a
        • 一个轻量级的替代方案是 Gnu On Windows (github.com/bmatzelle/gow/wiki)。只需打开命令提示符并运行bash。然后你可以编写 bash 命令。您还可以执行 bash 脚本。
        • 请注意,如果您的命令包含管道,那么您需要使用插入符号对其进行转义,例如:for /f "delims=" %%a in ('echo foobar^|sed -es/ foo/fu/') 做@set foobar=%%a
        【解决方案5】:

        需要小心一点,因为 Windows 批处理命令:

        for /f "delims=" %%a in ('command') do @set theValue=%%a
        

        与 Unix shell 语句的语义不同:

        theValue=`command`
        

        考虑命令失败导致错误的情况。

        在 Unix shell 版本中,仍然会发生对“theValue”的赋值,之前的任何值都被替换为空值。

        在 Windows 批处理版本中,处理错误的是 "for" 命令,并且永远不会到达 "do" 子句 -- 因此将保留 "theValue" 的任何先前值。

        要在 Windows 批处理脚本中获得更多类似 Unix 的语义,您必须确保分配发生:

        set theValue=
        for /f "delims=" %%a in ('command') do @set theValue=%%a
        

        将 Unix 脚本转换为 Windows 批处理时未能清除变量的值可能会导致细微错误。

        【讨论】:

        • 感谢您解释 Windows 和 *nix 之间的细微差别。
        • 还要记得转义command中的任何特殊字符;例如:for /f "delims=" %%a in ('command1 ^| command2') do set VAR=%%a.
        • @Bill_Stewart 你刚刚拯救了我的一天,有一段时间我认为将管道命令的输出分配给变量要困难得多
        【解决方案6】:

        当我在批处理文件中需要数据库查询的结果时,我会这样做:

        sqlplus -S schema/schema@db @query.sql> __query.tmp
        set /p result=<__query.tmp
        del __query.tmp
        

        关键在第 2 行:“set /p”通过“

        【讨论】:

          猜你喜欢
          • 2015-08-09
          • 2011-09-10
          • 1970-01-01
          • 1970-01-01
          • 2014-03-03
          • 2017-11-22
          • 1970-01-01
          • 2021-07-29
          • 1970-01-01
          相关资源
          最近更新 更多