Windows 如何在批处理文件中记录所有ECHO命令?

Windows 如何在批处理文件中记录所有ECHO命令?,windows,batch-file,command-prompt,Windows,Batch File,Command Prompt,我试图使用一个批处理文件作为一个选择你自己的冒险故事,在这个故事中,用户可以创建一个角色,并通过名字和故事中的角色来调用。一小时前我突然想到,如果在包含故事的批处理文件运行时或运行之后,它会记录所有的ECHO命令,以便稍后玩家可以读取他们在任何给定播放中所做的操作,那就太酷了 我希望日志文件如下所示: %日期%%time% (文件运行长度的echo命令显示的所有文本) 不幸的是,我所能想到的就是制作一个只包含日期和时间的日志文件。放置“>>StoryLog.txt”可以生成.txt文件,我在其中

我试图使用一个批处理文件作为一个选择你自己的冒险故事,在这个故事中,用户可以创建一个角色,并通过名字和故事中的角色来调用。一小时前我突然想到,如果在包含故事的批处理文件运行时或运行之后,它会记录所有的ECHO命令,以便稍后玩家可以读取他们在任何给定播放中所做的操作,那就太酷了

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

%日期%%time% (文件运行长度的echo命令显示的所有文本)


不幸的是,我所能想到的就是制作一个只包含日期和时间的日志文件。放置“>>StoryLog.txt”可以生成.txt文件,我在其中获取日期和时间,但它只是在屏幕上显示我希望批处理文件以回显文本形式显示的文本“>>StoryLog.txt”,如“您沿着路径向北走>>StoryLog.txt”。这当然行不通。我该怎么办?

在批处理脚本中,您不能直接这样做,但如果您定义了函数,您可以在函数返回之前输出函数块中的数据,这些数据也会写入日志文件,如下所示:

@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

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

为此,我使用以下命令:

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

由于一些编辑,我的另一个答案变得很长,这里有一个新的建议 (改动不大,但代码很容易阅读):


乱七八糟的编码,到处都是成对的行。最好创建一个新的LogEcho例程,该例程会回显到屏幕上,也会记录到文件中。您可以使用
tee
,也可用于Windows。有趣的技术。我曾希望这是一个漂亮的内存临时文件技巧,但它会作为一个带有单下划线文件名的文件写入磁盘。在我的测试中,我发现只需要一个
&
。。。i、 e.
set testout=^>^类型
dir%testout%
\只是用作缓冲区-因为我需要两次输出(给定一次)。它实际上是一个文件,每次都会被覆盖。是的,因为它是一个文件,你可以随心所欲地使用它-直到你在下一个“echo blabla%logg%”中覆盖它,你是对的,一个“&”就可以了(当我解决这个问题的时候,已经很晚了-一旦它成功了,就再也没有碰过它)+1,但是它失败了,文本像
%say%“这应该是一个插入符号,而不是两个”
%say%“一个符号^&fails”
也会失败。每种技巧都有其局限性。但我认为,对于最初的问题,这是可以的。我认为文本冒险不会利用这些特殊角色。
@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