使用 Windows 批处理文件中的命令结果设置变量的值

Posted

技术标签:

【中文标题】使用 Windows 批处理文件中的命令结果设置变量的值【英文标题】:Set the value of a variable with the result of a command in a Windows batch file 【发布时间】: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 而不是命令的输出。

【问题讨论】:

【参考方案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”通过“

【讨论】:

以上是关于使用 Windows 批处理文件中的命令结果设置变量的值的主要内容,如果未能解决你的问题,请参考以下文章

Windows批处理

即使在设置 EnableDelayedExpansion [重复] 之后,也无法在批处理文件中的 for 循环内设置变量值

一个 IF 语句,用于检查并执行 Windows 批处理文件中每个设置变量的命令

在 Windows 命令行中使用批处理文件中的参数

如何使用 ImageMagick 在 Windows 批处理文件中捕获图像比较结果

使用管道将 Windows 命令解析为批处理文件中的变量 [重复]