批量设置输出和命令错误以分隔变量 [英] Batch set output and error of a command to separate variables

查看:63
本文介绍了批量设置输出和命令错误以分隔变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆