如何在 BATCH 文件中记录所有 ECHO 命令?

问题描述 投票:0回答:5

我正在尝试使用 BATCH 文件作为选择您自己的冒险故事,其中用户可以创建一个角色并由故事中的角色按名称等进行调用。一小时前,我突然意识到,如果包含故事的 BATCH 文件运行时或运行之后,它会记录所有 ECHO 命令,以便稍后玩家可以读取他们在任何给定的游戏投掷中所做的事情,那就太酷了。

我希望日志文件如下所示:

%日期%%时间% (回显命令显示文件运行长度的所有文本)

不幸的是,我所能想到的就是制作一个仅包含日期和时间的日志文件。将“>> StoryLog.txt”放入 .txt 文件中,我会在其中获取日期和时间,但它只在我希望批处理文件在回显 txt 中显示的内容之后显示文本“>> StoryLog.txt”屏幕上显示“您沿着路径向北>> StoryLog.txt”。这自然是行不通的。我该怎么办?

windows batch-file command-prompt
5个回答
8
投票

为此目的,我使用以下内容:

set LogFile=somepath\logfile.txt
set logg=^> _^&type _^&type _^>^>%LogFile%
echo this goes to screen AND file! %logg%

这有点棘手。 因此,让我们将该线路拆解为四个部分:

set logg=      ^> _          ^&type _           ^&type _^>^>%LogFile%

想法是将行打印到临时文件(名为

_
)(第二部分) 然后将该文件的内容输入到屏幕上(第三部分) 然后将其输入日志文件(第四部分)。

将所有内容放入变量(第一部分),这样您就不必在每一行中键入该怪物字符串。 (这就是为什么

>
&
^
转义)

所以每次使用

echo whatever %logg%

它将出现在屏幕上并写入

%logfile%

请注意,这也将起作用:

 %logg% echo whatever

编辑djangofan: 另外,您可以使用函数来做到这一点:

@ECHO off
:: do not enable delayed expansion since it will break this method
SETLOCAL ENABLEEXTENSIONS
SET LogFile=logfile.out
SET Logg=^> tmp.out^&^& type tmp.out^&^&type tmp.out^>^>%LogFile%

CALL :logit "This is my message!"
CALL :logit "Hear my thunder?"

GOTO :end
:logit
ECHO %~1 %Logg%
DEL /Q tmp.out
EXIT /B 0
:end
pause

编辑 斯蒂芬: 如果您使用 CALL,则

%logg%
就有点过分了。在这种情况下,我只会使用:

:logit
echo %~1
echo %date%,%time% - %~1 >>logfile
exit /b 0

这可能是原始问题的最佳解决方案,因为日期/时间将写入日志文件,但不会显示在屏幕上。 顺便说一句:您不必每次使用临时文件时都删除它,只需在批处理结束之前删除它一次即可。


4
投票

由于我的其他答案由于一些编辑而变得很长,这里有一个新建议 (没有太大改变,但它使代码很容易阅读):

@ECHO off
SET LogFile=logfile.out
set "say=call :logit "

%say% "This is my message!"
%say% "Hear my thunder?"

GOTO :end
:logit
ECHO %~1 
echo %date% %time% - %~1 >>%logfile%
EXIT /B 0
:end

0
投票

您无法在批处理脚本中执行此操作,但如果您定义函数,则可以在函数块内输出数据,这些数据也会在函数返回之前写入日志文件,如下所示:

@ECHO off
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
echo. 2>outfile.log

CALL :functionPerson "Jon Doe" jump
GOTO :END
:functionPerson fullname action
  ECHO fullname is ^"%~1^"
  ECHO action is %2
  ECHO %1 performs action %2>> outfile.log
EXIT /B 0
:END
pause

0
投票

每次你

echo
让玩家知道发生了什么,你也可以
echo
进入你的日志文件,在行的开头添加日期和时间:)对我来说很简单。 但不知道你的脚本看起来如何。


0
投票

@Stephan,这是正确的。谢谢!

虽然这是一篇很老的帖子,但它仍然具有相关性。这正是我多年来一直想知道的,最后偶然发现了这一点。我见过一些使用 PowerShell 或其他 .exe 的示例,但是,我一直想坚持使用基本的 Windows 命令脚本语言,因为,我倾向于与那些不熟悉 PowerShell 之类的人分享这些语言,并且不熟悉这些语言。想要依赖其他人可能没有的 exe。

没有涵盖的一些事情是如何处理可能包含空格或从其他变量派生的日志文件路径以及我想要在其中创建新文件,然后附加到它的位置。所有这些都在下面的可执行脚本示例中进行了介绍和说明:

:DEFINE_VARIABLES
set CLIENT_NAME=ClientName
set PROJECT_NUMBER=XXXXXXXX
set PROJECT_NAME=ProjectName
set PROJECT_ROOT_PATH=\\Server\Share\%CLIENT_NAME%\%PROJECT_NUMBER%
set BUILDING_ID=BLDG1

title Update the %CLIENT_NAME% %PROJECT_NAME% %BUILDING_ID% File

:CREATE_LOG_FILE
set LOG_FILE_LOCATION=C:\Temp\%BUILDING_ID%
set LOG_FILE_NAME=%CLIENT_NAME%_%PROJECT_NAME%_%BUILDING_ID%_Update_File_log_%DATE:~-4%%DATE:~-10,-8%%DATE:~-7,-5%_@_%TIME:~-11,2%%TIME:~-8,2%%TIME:~-5,2%.log
set LOG_FILE=%LOG_FILE_LOCATION%\%LOG_FILE_NAME%
set LOGG_NEW=^> _^&type _^&type _^>"%LOG_FILE%"
set LOGG=^> _^&type _^&type _^>^>"%LOG_FILE%"
echo Update the %CLIENT_NAME% %PROJECT_NAME% %BUILDING_ID% File %LOGG_NEW%
echo. %LOGG%
echo Process being run by: %USERNAME% %LOGG%
echo on Computer: %COMPUTERNAME% %LOGG%
echo. %LOGG%

注意事项:

  1. 定义 LOGG 变量时,如果路径和/或文件名包含空格,则需要在 LOG_FILE 变量周围添加引号 (")。这是唯一可以执行此操作的地方。
  2. LOGG 变量假定追加文件,而 LOGG_NEW 将创建一个新的日志文件。

再次感谢您的帮助,减少了我的代码行数,让我自己和其他人更容易理解。

HTH 其他可能仍在寻找这个问题并寻找答案的人。

© www.soinside.com 2019 - 2024. All rights reserved.