将 Windows 批处理文件中的输出重定向到脚本内部。

huangapple go评论66阅读模式
英文:

Redirect output from a Windows batch file within the script

问题

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

我有一个解决方案,需要通过从另一个批处理文件(tee_start.bat)再次调用主脚本来进行“引导”。

我确定我要避免的是重构调用main.bat的所有其他脚本以使用tee命令 - 如果我可以在main.bat中放置一些新代码,那将是一个更小、更安全的更改。

是否有一种方法可以做到这一点,而不涉及像我下面所做的重新启动主文件?
例如,是否有一个cmd.exe或powershell.exe命令可以说“接管我的当前标准输出并将其tee出来” - 或者tee是否以某种方式支持此行为,而我错过了它?
或者,作为替代方案,我应该满足于我已经实施的最不侵入性的方法?

我已经实施了一个解决方案如下:

main.bat

REM 这是引导模式的示例 - 它将重新启动此主脚本,并记录所有输出
call tee_start.bat %~dpnx0 %*

echo 此输出应同时出现在屏幕控制台和日志文件中

tee_start.bat

REM 为了引导输出重定向 - 此脚本被调用两次 - 一次用powershell tee命令初始化日志记录
REM 第二次,它只是回显日志信息并返回而不执行任何操作
if x%LOG_FILE% neq x (
    echo 引导过程:%1%
    echo 转义参数:%ADDL_ARGS%
    echo 日志文件:%LOG_FILE%
    goto :EOF
)

set ADDL_ARGS=
:loop_start
shift
if x%1 == x goto :after_loop
REM 保留输入中的参数结构(带引号或不带引号)
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%"
英文:

I am trying to make a Windows batch file (the main script) redirect all of it's output to a file while still displaying it on the screen. I cannot change all the code that calls the main script - I need to change the main script itself.

I have a solution that requires "bootstrapping" the main script by calling it again from another bat file (tee_start.bat).
What I'm sure I want to avoid is refactoring all the other scripts that call main.bat to use the tee command - it will be a much smaller, safer change if I can put some new code in main.bat.

Is there a way to do this that does not involve restarting the main file as I am doing below?
For example, is there a cmd.exe or powershell.exe command that says "Take my current STDOUT and tee it" - or does tee somehow support this behavior and I missed it?
Or, alternatively, should I settle for what I have implemented as the least invasive method?

I have implemented a solution as follows:

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%"

答案1

得分: 4

以下是翻译好的部分:

<!-- language-all: sh -->

我建议采用以下方法,无需辅助的 `tee_start.bat` 文件:

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

@echo off & setlocal

if defined LOGFILE goto :DO_IT

    set "LOGFILE=log.txt"
    :: 使用重定向重新调用
    "%~f0" %* 2>&1 | powershell -NoProfile -Command "$input | Tee-Object -FilePath \"%LOGFILE%\"; \"[output captured in: %LOGFILE%]\""
    exit /b


:DO_IT

:: 示例输出
echo [args: %*]
echo 输出到标准输出
echo 输出到标准错误 >&2
echo [完成]

Tee-Object 使用固定的字符编码,在 Windows PowerShell(powershell.exe)中是“Unicode”(UTF-16LE),在 PowerShell(Core)7+(pwsh.exe)中是(无BOM的UTF-8)。


<details>
<summary>英文:</summary>

&lt;!-- language-all: sh --&gt;

I suggest the following approach, which makes do without the aux. `tee_start.bat` file:

`main.bat` content (outputs to `log.txt` in the current folder; adjust as needed):

@echo off & setlocal

if defined LOGFILE goto :DO_IT

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

:DO_IT

:: Sample output
echo [args: %*]
echo to stdout
echo to stderr >&2
echo [done]


* [`Tee-Object`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/tee-object) uses a _fixed_ character encoding, which is notably &quot;Unicode&quot; (UTF-16LE) in Windows PowerShell ([`powershell.exe`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe)), and (BOM-less UTF-8) in PowerShell (Core) 7+ ([`pwsh.exe`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pwsh)).



</details>



huangapple
  • 本文由 发表于 2023年1月9日 04:08:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050918.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定