windows - 重定向脚本内 Windows 批处理文件的输出

标签 windows powershell batch-file cmd tee

我正在尝试制作一个 Windows 批处理文件(主脚本)将其所有输出重定向到一个文件,同时仍将其显示在屏幕上。我无法更改调用主脚本的所有代码 - 我需要更改主脚本本身。

我有一个解决方案,需要通过从另一个bat文件(tee_start.bat)再次调用它来“引导”主脚本。 我确信我想要避免的是重构所有其他调用 main.bat 的脚本以使用 tee 命令 - 如果我可以在 main.bat 中放入一些新代码,这将是一个更小、更安全的更改。

有没有一种方法可以做到这一点,而不需要像我下​​面所做的那样重新启动主文件? 例如,是否有一个 cmd.exe 或 powershell.exe 命令说“获取我当前的 STDOUT 并发球” - 或者发球是否以某种方式支持此行为而我错过了? 或者,我应该满足于我所实现的侵入性最小的方法吗?

我实现了如下解决方案:

main.bat

REM this is an example of bootstrap mode - it will restart this main script with all output logged
call tee_start.bat %~dpnx0 %*

echo This output should appear both in the screen console and in a log file

tee_start.bat

REM in order to bootstrap the output redirection - this script gets called twice - once to initialize logging with powershell tee command
REM second time, it just echoes log information and returns without doing anything
if x%LOG_FILE% neq x (
    echo Bootstrapped Process: %1%
    echo Escaped Arguments: %ADDL_ARGS%
    echo Log File: %LOG_FILE%
    goto :EOF
)

set ADDL_ARGS=
:loop_start
shift
if x%1 == x goto :after_loop
REM preserve argument structure (quoted or not) from the input
set ADDL_ARGS=%ADDL_ARGS% \"%~1\"
goto loop_start
:after_loop

SET LOG_FILE=/path/to/some/logfile.log

powershell "%1% %ADDL_ARGS% 2>&1 | tee -Append %LOG_FILE%"

最佳答案

我建议采用以下方法,无需辅助即可解决。 tee_start.bat 文件:

main.bat内容(输出到当前文件夹中的log.txt;根据需要调整):

@echo off & setlocal

if defined LOGFILE goto :DO_IT

    set "LOGFILE=log.txt"
    :: Reinvoke with teeing
    "%~f0" %* 2>&1 | powershell -NoProfile -Command "$input | Tee-Object -FilePath \"%LOGFILE%\"; \"[output captured in: %LOGFILE%]\""
    exit /b


:DO_IT

:: Sample output
echo [args: %*]
echo to stdout
echo to stderr >&2
echo [done]
  • Tee-Object使用固定字符编码,尤其是 Windows PowerShell 中的“Unicode”(UTF-16LE) ( powershell.exe ),以及 PowerShell (Core) 7+ 中的(BOM-less UTF-8)( pwsh.exe)。

关于windows - 重定向脚本内 Windows 批处理文件的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75050918/

相关文章:

batch-file - 批处理文件打开一个具有部分文件夹名称的文件夹

.net - 找不到来自源的事件 ID 的说明

c++ - Windows XP中如何判断一个驱动器是否支持硬链接(hard link)?

powershell - 如何找到尝试连接的端口?

powershell - 获取 AzureRmResourceGroup : The term 'Get-AzureRmResourceGroup' is not recognized as the name of a cmdlet

linux - Windows powershell 中的 tail -f 是什么?

batch-file - 我需要剪切 MP4 视频。开头部分和结尾部分以批处理方式

windows - powershell get-childitem 找不到包含 [ ] 的文件

linux - Linux + windows 的 hadoop 节点

ruby - 最佳批量大小 PostgreSQL 更新