在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/