windows - 批量设置命令的输出和错误以分隔变量

标签 windows batch-file cmd windows-7 io-redirection

在Windows 7批处理(cmd.exe命令行)中,我试图将命令的标准输出(stdout)和标准错误(stderr)重定向到单独的变量(因此第一个变量设置为输出,并且第二个变量设置为错误(如果有))而不使用任何临时文件。我试了又试,但没有成功。

那么,将命令的输出和错误设置为单独变量的有效方法是什么?

最佳答案

您可以使用两个嵌套的 for/F 循环,其中内部循环捕获标准输出,外部循环捕获重定向错误。由于内部实例是一个新的 cmd 进程,因此捕获的文本不能仅分配给变量,因为执行完成后它将丢失。相反,我在每一行前面加上 | 并将其回显到标准输出。外循环检测前导 | 并相应地分隔行:

@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 字节;

所有这些限制对于标准输出和标准错误都适用。

<小时/>

编辑:

这是上述代码的改进变体。有关空行和以分号 ; 开头的行的问题已解决,其他限制仍然存在:

@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 不会出现空行;当然,这个前缀稍后会被删除。此更改还隐式解决了 ; 问题。

由于findstr中嵌套了管道,只要实际需要其管道功能,就需要多次转义来隐藏|字符。

关于windows - 批量设置命令的输出和错误以分隔变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34486993/

相关文章:

用于 Windows xampp 的 php-apc

linux - 从Fedora Linux主机到Windows目标的交叉编译Rust找不到依赖项

powershell - 使用Windows截图并在cmd中草绘剪贴板临时图像

c# - 编译时从数据库获取dll版本号

java - Jar 输出中的 UTF-8 编码损坏

windows - Docker for Windows 错误 : "Hardware assisted virtualization and data execution protection must be enabled in the BIOS"

batch-file - 当文件已经存在时,如何在批处理文件的开头退出批处理?

Python timeit命令行错误: "SyntaxError: EOL while scanning string literal"

java - 从java代码获取cmd命令的输出

java - 测试大约 20k 客户端与服务器的连接