使用 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] 以&::
结尾的部分为行尾注释,可以忽略。我把它们只用于宏封闭
2] 行首的;;
将被忽略,因为;
是批处理脚本的标准分隔符。将它放在那里是为了提醒注释并进一步增强宏定义的分配位置。
3]使用的技术称为“宏”,它将命令分配给变量,并在调用变量时执行命令。
4]定义的第一个宏包含两部分:
set "[[=>"#" 2>&1&set/p "
和
set "]]==<# & del /q # >nul 2>&1"
由&
分隔,这使我可以在一行上定义它们。第一个获取命令的输出并将其重定向到文件#
。并添加set/p
以使用set /p
technique 开始读取文件。第二个宏以<#
完成set /p
读取,然后删除文件。两个宏之间的文本是变量的名称。类似set /p myVariable=<#
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 批处理文件中的命令结果设置变量的值的主要内容,如果未能解决你的问题,请参考以下文章
即使在设置 EnableDelayedExpansion [重复] 之后,也无法在批处理文件中的 for 循环内设置变量值
一个 IF 语句,用于检查并执行 Windows 批处理文件中每个设置变量的命令