批量设置命令的输出和错误以分隔变量 [英] Batch set output and error of a command to separate variables
问题描述
在 Windows 7 批处理(cmd.exe 命令行)中,我试图将命令的标准输出(stdout)和标准错误(stderr)重定向到分隔变量(因此第一个变量设置为输出,并且第二个变量设置为错误(如果有))而不使用任何临时文件.我已经尝试过,但没有成功.
In windows 7 batch (cmd.exe command-line), I am trying to redirect the standard output (stdout) and standard error (stderr) of a command to separate variables (so the 1st variables is set to the output, and the 2nd variable is set to the error (if any)) without using any temporary files. I have tried and tried with no success at this.
那么,将命令的输出和错误设置为分隔变量的有效方法是什么?
So, what would be a working way to set the output and error of a command to separate variables?
推荐答案
你可以使用两个嵌套的 for/F
循环,其中内部一个捕获标准输出,外部一个捕获重定向错误.由于内部实例一个新的 cmd
进程,捕获的文本不能只分配给一个变量,因为它会在执行完成后丢失.相反,我在每一行前面加上 |
并将其回显到标准输出.外部循环检测前导 |
并相应地分隔行:
You could go for two nested for /F
loops, where the inner one captures the standard output and the outer one captures the redirected error. Since the inner one instances a new cmd
process, the captured text cannot just be assigned to a variable, because it will be lost after execution finishes. Rather I precede every line with |
and just echo it to the standard output. The outer loop detects the leading |
and separates the lines accordingly:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "STDOUT="
set "STDERR="
(set LF=^
%=empty line=%
)
for /F "delims=" %%E in ('
2^>^&1 ^(^
for /F "delims=" %%O in ^('^
command_line^
'^) do @^(^
echo ^^^|%%O^
^)^
^)
') do (
set "LINE=%%E"
if "!LINE:~,1!"=="|" (
set "STDOUT=!STDOUT!!LINE:~1!!LF!"
) else (
set "STDERR=!STDERR!!LINE!!LF!"
)
)
echo ** STDOUT **!LF!!STDOUT!
echo ** STDERR **!LF!!STDERR!
endlocal
exit /B
以下限制适用于代码:
- 空行被忽略;
- 以分号
;
开头的行将被忽略; - 感叹号
!
丢失,因为启用了延迟的环境变量扩展; - 以管道字符
|
开头的行可能分配错误; - 数据总大小不得超过 8190 字节;
- empty lines are ignored;
- lines that begin with a semicolon
;
are ignored; - exclamation marks
!
are lost, because delayed environment variable expansion is enabled; - lines that begin with a pipe character
|
may be assigned wrongly; - the overall size of data must not exceed 8190 bytes;
所有这些限制都适用于标准输出和标准错误.
All of those limitations are true for both standard output and standard error.
这是上述代码的改进变体.空行和以分号;
开头的行的问题已解决,其他限制仍然存在:
Here is an improved variant of the above code. The issues concerning empty lines and lines beginning with a semicolon ;
are resolved, the other restrictions still remain:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "STDOUT="
set "STDERR="
(set LF=^
%=empty line=%
)
for /F "delims=" %%E in ('
2^>^&1 ^(^
for /F "delims=" %%O in ^('^
command_line ^^^^^^^| findstr /N /R "^"^
'^) do @^(^
echo ^^^^^^^|%%O^
^)^
^) ^| findstr /N /R "^"
') do (
set "LINE=%%E"
set "LINE=!LINE:*:=!"
if "!LINE:~,1!"=="|" (
set "STDOUT=!STDOUT!!LINE:*:=!!LF!"
) else (
set "STDERR=!STDERR!!LINE!!LF!"
)
)
echo ** STDOUT **!LF!!STDOUT!
echo ** STDERR **!LF!!STDERR!
endlocal
exit /B
findstr
命令用于在每一行前面加上一个行号加上 :
,因此对于 for/F
来说,没有一行是空的;当然,这个前缀稍后会被删除.此更改还隐式解决了 ;
问题.
The findstr
command is used to precede every single line with a line number plus :
, so no line appears empty to for /F
; this prefix is removed later on, of course. This change also solves the ;
issue implicitly.
由于findstr
中嵌套了管道,所以需要多次转义才能隐藏|
字符,只要实际需要其管道功能即可.
Because of the nested piping into findstr
, multiple escaping is required to hide the |
character as long as its piping function is actually needed.
这篇关于批量设置命令的输出和错误以分隔变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!