总而言之,目标有两个:
- 创建一个仅包含失败的命令以及这些命令生成的错误消息的日志文件。
- 防止控制台输出(成功或失败),除了我想要回显的消息。
我正在尝试弄清楚如何在批处理文件中执行如下操作:
@CmdThatWillFail || Redirect original command + error message to a file
我正在尝试捕获原始命令及其伴随的错误消息——但前提是出现错误,同时抑制所有输出到控制台。我意识到我不能在每个命令前使用 @,也不能关闭 ECHO 来捕获原始命令,所以我甚至不确定这是否可行。
除了使用 Doskey 之外,我不知道还有什么方法可以扩展或引用之前运行的命令。我尝试过使用doskey /history
和more
其他方法来检索最后一个命令,但还没有想出可行的解决方案。我也尝试过备用数据流,但我觉得这不是一个好的解决方案。最后,我尝试了以下几种组合:
@ECHO OFF
ECHO %DATE% %TIME:~0,-3% > Log.txt
CALL :Function >>Log.txt 2>&1
ECHO Script finished. Press any key to exit. . . && PAUSE >NUL
EXIT /B
:Function
@ECHO ON
DIR FileThatDoesNotExist >NUL
DIR Log.txt >NUL
@ECHO This will show up in the log, but not the console.
@ECHO This will show up in the console, but not the log. >CON:
@ECHO How can this be redirected to show up in both log and console?
@ECHO OFF
控制台输出:
This will show up in the console, but not the log.
How can this be redirected to show up in both log and console?
Script finished. Press any key to exit. . .
- 使用
>CON
(谢谢摧毁666):Function
可以完美地回显到控制台并防止回显到日志。
日志输出:
Thu 05/11/2023 12:00:00
C:\Scripts>DIR FileThatDoesNotExist 1>NUL
File Not Found
C:\Scripts>DIR Log.txt 1>NUL <----- How to suppress commands that succeed?
This will show up in the log, but not the console.
- 失败的命令
DIR FileThatDoesNotExist >NUL
及其生成的错误消息被记录下来File Not Found
,并且两者都被从控制台中隐藏。这正是我所寻找的。
仍需解决的问题:
C:\Scripts>DIR Log.txt 1>NUL
已成功完成但仍显示在日志中 - 我想从控制台中抑制成功的命令(及其输出)和日志。如何实现呢?- 如何才能让某些内容同时回显到控制台和日志中?
我试图保持这个相对简单和干净并且不引入 powershell 调用,使用 Tee-Object,第三方工具等。
有什么想法吗?
答案1
更新根据编辑。
如果不使用外部工具,您的目标看起来就不可能实现,或者至少无法合理实现。
>
据我所知,涉及 CMD 和流的唯一可能操作是:
2>&1
,2>&3
,3>&9
- 在编号流之间重定向,其中1
和2
是stdout
并且stedrr
并且直到 的其他流9
不被保留1>NUL
- 重定向至 void2>CON
- 重定向到控制台输出
例如,复制或重用流(可以解决您剩下的两个问题之一)在没有外部工具(如上述 tee)的情况下不太可行。安装它比尝试奇怪的解决方法(最终会使您的代码看起来很糟糕)更值得推荐。
另外,如果你使用 PowerShell,那么Tee 对象默认可用。
答案2
如果您希望对正在发生的事情进行更有限的控制,则可以使用以下方法。 @Destroy666 方法可能是您所需要的,但这是解决问题的另一种方法。您可能还希望以任何您需要的方式重定向 for /f 函数中的输出。
@ECHO OFF
ECHO %DATE% %TIME:~0,-3% > Log.txt
for /f "delims=" %%l ('command_here') do call :EvalFunction "%%l" "%ERRORLEVEL%"
ECHO Script finished. Press any key to exit. . . && PAUSE >NUL
goto :EOF
:EvalFunction
Set TextError=%~1
Set IntError=%~2
if [%IntError%]==[0] goto :EOF
echo %TextError% >Log.txt
goto :EOF
'''