批量设置输出和命令错误以分隔变量 [英] 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
以下限制适用于该代码:
The following restrictions apply to the code:
- 空行将被忽略;
- 以分号
;
开头的行将被忽略; - 感叹号
!
丢失,因为启用了延迟的环境变量扩展;
以竖线字符 - 行可能分配有误;
- 数据的总大小不得超过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屋!