显示Windows命令提示符输出并将其重定向到文件

355 cmd stdout batch-file tee

如何在Windows命令提示符下运行命令行应用程序并同时显示输出并重定向到文件?

例如,如果我要运行该命令dir > test.txt,则会将输出重定向到调用的文件test.txt而不显示结果.

我怎么能写一个命令显示输出输出重定向到在Windows命令提示符下一个文件,类似于teeUnix上的命令?

Sax*_*uce 140

要扩展davor的答案,您可以像这样使用PowerShell:

powershell "dir | tee test.txt"
Run Code Online (Sandbox Code Playgroud)

如果您尝试在当前目录中重定向exe的输出,则需要.\在文件名上使用,例如:

powershell ".\something.exe | tee test.txt"
Run Code Online (Sandbox Code Playgroud)

  • 这是最接近的答案:它适用于默认安装,因为PS已经存在于大多数机器上,尤其是服务器上. (8认同)
  • 要查看所有输出,不要忘记使用`2>&1`将STDERR重定向到STDOUT,例如`node 2>&1 | tee debug_log.txt` (6认同)
  • 喜欢它:)无论如何{powershell"ping -n 10 localhost | tee test.txt"}将展示更好的发球派对 (3认同)
  • 请注意,powershell中的`dir`是`Get-ChildItem`的别名,它与cmd的内部`dir`命令不同.你需要`powershell"cmd/c dir | tee test.txt"`如果你想要cmd内部版本 (3认同)
  • 考虑添加“-Append”,这样日志文件就不会在每个命令启动时被截断。例如`powershell "node server.js 2>&1 | tee -Append app.log"` (2认同)
  • 使用 `2>&1` 任何 stderr 输出都会导致显示“NativeCommandError”,并与实际输出混合。为了防止这种情况,请使用`powershell ".\something.exe 2>&1 | foreach {\"$_\"} | tee test.txt"`。这会将任何错误记录转换为纯文本,然后再将其发送到“tee”。 (2认同)

NSP*_*GNk 130

我能够找到将输出重定向到文件然后重定向到控制台的解决方案/解决方法:

dir > a.txt | type a.txt
Run Code Online (Sandbox Code Playgroud)

其中dir是需要重定向输出的命令,a.txt是存储输出的文件.

  • 这满足了答案,但是在dir命令完成之后而不是在生成数据时输出数据. (97认同)
  • 它会工作,但如果命令等待来自stdin的输入,你将会卡住. (8认同)
  • 我喜欢这个简单的答案!我发现某些命令的输出需要```而不是```,比如`ping`或`7z.exe` (4认同)
  • @lii re:`处理输出到stderr` - 添加`2>&1`重定向,所以它是这样的:`dir 2>&1> a.txt&type a.txt`,你_should_将stderr与stdout混合在一起. (4认同)

Bri*_*sen 92

有一个Unix tee命令的Win32端口,就是这样做的.请参阅http://unxutils.sourceforge.net/http://getgnuwin32.sourceforge.net/

  • 该链接指向Unix命令tee的Windows实现,因此它可以在Windows上运行. (17认同)
  • 如果你像我一样努力寻找GnuWin32的`tee`包,你可以在http://gnuwin32.sourceforge.net/packages/coreutils.htm找到它. (8认同)
  • 是的,投票给答案和评论.我实际上更喜欢CygWin,因为它拥有一切,但有些人更喜欢他们可以挑选的非DLL工具. (3认同)
  • 许多Unix实用程序也由GnuWin32项目移植,请参阅http://gnuwin32.sourceforge.net/. (3认同)
  • UnxUtils最后更新于2003年; GnuWin32更新一点. (2认同)

Dav*_*vic 49

看看这个:wintee

不需要cygwin.

我确实遇到并报告了一些问题.

你也可以检查unxutils,因为它包含tee(并且不需要cygwin),但要注意输出EOL在这里类似于UNIX.

最后,但并非最不重要的,如果您有PowerShell,您可以尝试Tee-Object.键入get-help tee-objectPowerShell控制台以获取更多信息.

  • 为什么投票失败?这里有95%的回复有一个共同点:只有在初始命令完成后才会重定向输出:阅读注释.UNIX实用程序`tee`输出实时.`wtee`具有相同的功能.如果你不介意这些错误,它会做得很好. (4认同)

小智 43

@ tori3852

我找到

dir > a.txt | type a.txt
Run Code Online (Sandbox Code Playgroud)

没有工作(只有dir列表的前几行 - 怀疑某种过程分叉,第二部分,'type'命令在可怕列表完成之前终止?),所以我使用了:

dir > z.txt && type z.txt
Run Code Online (Sandbox Code Playgroud)

它做了 - 顺序命令,一个在第二个开始之前完成.

  • 如果要确保即使`dir`命令失败也要执行`type`命令,你应该使用`&`而不是`&&`.当命令中存在某种形式的错误并且您仍希望在控制台上看到日志文件时,这非常有用.请参阅[Microsoft的文章](http://support.microsoft.com/kb/279253).但是,这会将`%errorlevel%`设置为`type`的错误级别(将为0). (15认同)

小智 23

一个简单的C#控制台应用程序可以做到这一点:

using System;
using System.Collections.Generic;
using System.IO;

namespace CopyToFiles
{
    class Program
    {
        static void Main(string[] args)
        {
            var buffer = new char[100];
            var outputs = new List<TextWriter>();

            foreach (var file in args)
                outputs.Add(new StreamWriter(file));

            outputs.Add(Console.Out);

            int bytesRead;
            do
            {
                bytesRead = Console.In.ReadBlock(buffer, 0, buffer.Length);
                outputs.ForEach(o => o.Write(buffer, 0, bytesRead));
            } while (bytesRead == buffer.Length);

            outputs.ForEach(o => o.Close());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需将source命令传递给程序,并提供要复制输出的任何文件的路径.例如:

dir | CopyToFiles files1.txt files2.txt 
Run Code Online (Sandbox Code Playgroud)

将显示dir的结果,并将结果存储在files1.txt和files2.txt中.

请注意,上面的错误处理方式并不多(任何事情!),实际上可能并不需要支持多个文件.

  • 你不需要visual studio来编译它,命令行工具实际上是免费的.只是谷歌".net sdk下载"的链接(直接链接似乎改变,但谷歌总是似乎工作). (19认同)
  • Visual Studio Express也是免费的,但我仍然只是使用tee. (13认同)
  • cygwin很难安装.向你推荐,因为这是我正在寻找的. (7认同)
  • 嗯,什么都不下载tee/cygwin或用我辛苦赚来的现金购买MSVS这样一个小小的节目?这是一个艰难的:-) (5认同)

Dan*_*ski 21

不幸的是没有这样的事情.

Windows控制台应用程序只有一个输出句柄.(好吧,有两个STDOUT,STDERR但这里没关系)>将通常写入控制台句柄的输出重定向到文件句柄.

如果你想要某种多路复用,你必须使用一个外部应用程序,你可以将输出转移到.然后,此应用程序可以再次写入文件和控制台.

  • `tee` on*nix也是一个单独的应用程序,而不是shell上的一些重定向 (2认同)

MTS*_*MTS 19

虽然它有点难看,但这有效:

dir >_ && type _ && type _ > a.txt
Run Code Online (Sandbox Code Playgroud)

它比其他一些解决方案更灵活,因为它可以逐个语句地工作,因此您也可以使用它进行追加.我在批处理文件中使用这一点来记录和显示消息:

ECHO Print line to screen and log to file.  >_ && type _ && type _ >> logfile.txt
Run Code Online (Sandbox Code Playgroud)

是的,您可以重复ECHO语句(一次用于屏幕,第二次重定向到日志文件),但这看起来一样糟糕,并且有点维护问题.至少这种方式您不必在两个地方对消息进行更改.

请注意,_只是一个简短的文件名,因此您需要确保在批处理文件的末尾删除它(如果您使用的是批处理文件).

  • 这仅在您希望在进程运行后显示内容时才有用.这不是一个难以解决的问题. (2认同)
  • +1 这就是我一直以来的做法。我相信这是原始问题的正确答案,应该如此标记。正如 @MTS 暗示的那样,诀窍在于您实际上写入两个文件:每个文件创建一个每个命令/行(因此每次都会覆盖一个“&gt;”),然后将该行键入到屏幕上(输入_),最后,再次输入它并使用“&gt;&gt;”将其输出(所有长附加内容)重定向到日志文件。尽管我喜欢简单的“_”临时文件,但我多年来一直这样做。我总是做“tmp.txt”或类似的东西。是啊,之后就删掉吧。 (2认同)

小智 16

mtee是一个小型实用程序,可以很好地实现此目的.它是免费的,源是开放的,它只是工作.

您可以在http://www.commandline.co.uk找到它 .

在批处理文件中用于显示输出并同时创建日志文件,语法如下所示:

    someprocess | mtee /+ mylogfile.txt
Run Code Online (Sandbox Code Playgroud)

其中/ +表示附加输出.

假设您已将mtee复制到PATH中的文件夹中,当然.

  • 这似乎要等到输出完成后再输出到文件或控制台。 (2认同)

小智 11

我想对Saxon Druce的优秀答案进行一些扩展.

如上所述,您可以在当前目录中重定向可执行文件的输出,如下所示:

powershell ".\something.exe | tee test.txt"
Run Code Online (Sandbox Code Playgroud)

但是,这只会记录stdouttest.txt.它也不会记录stderr.

显而易见的解决方案是使用这样的东西:

powershell ".\something.exe 2>&1 | tee test.txt"
Run Code Online (Sandbox Code Playgroud)

但是,这对所有人都不适用something.exe.有些人something.exe会将其解释2>&1为一个论点而失败.正确的解决方案是只在something.exe它周围有撇号和它的开关和参数,如下所示:

powershell ".\something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt
Run Code Online (Sandbox Code Playgroud)

  • 所有这一切都是完全错误的.它对我来说根本不起作用.由于显而易见的原因,最后一个命令"tee"不被识别为内部或外部命令.对于cmd行中的"2>&1",任何输出到stderr都会导致PowerShell出错. (2认同)

Ste*_*ane 9

我同意Brian Rasmussen的观点,unxutils端口是最简单的方法.在他的脚本页面批处理文件部分中,Rob van der Woude提供了有关使用MS-DOS和CMD命令的大量信息.我认为他可能有一个原生的解决方案来解决你的问题,在那里挖掘后我发现了TEE.BAT,这似乎只是一个MS-DOS批量语言实现的tee.这是一个非常复杂的批处理文件,我的倾向仍然是使用unxutils端口.

  • 请注意,在命令完成后将使用TEE.BAT输出,就像附近发布的"dir> a.txt | type a.txt"示例一样. (10认同)

jkd*_*dba 8

如果您在Windows环境路径中有cygwin,则可以使用:

 dir > a.txt | tail -f a.txt
Run Code Online (Sandbox Code Playgroud)

  • 如果您打算使用Cygwin,它会配备T恤. (7认同)

ras*_*hok 7

dir 1>a.txt 2>&1 | type a.txt

这将有助于重定向STDOUT和STDERR


Aac*_*ini 6

我知道这是一个非常古老的话题,但在之前的答案中,没有完整实现用 Batch 编写的实时 Tee。我下面的解决方案是一个 Batch-JScript 混合脚本,它使用 JScript 部分只是为了从管道命令中获取输出,但数据的处理是在 Batch 部分完成的。这种方法的优点是任何 Batch 程序员都可以修改此程序以满足特定需求。该程序还正确处理了其他 Batch 文件产生的 CLS 命令的输出,即在检测到 CLS 命令输出时清屏。

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion

rem APATee.bat: Asynchronous (real time) Tee program, Batch-JScript hybrid version
rem Antonio Perez Ayala

rem The advantage of this program is that the data management is written in Batch code,
rem so any Batch programmer may modify it to fit their own needs.
rem As an example of this feature, CLS command is correctly managed

if "%~1" equ "" (
   echo Duplicate the Stdout output of a command in the screen and a disk file
   echo/
   echo anyCommand ^| APATee teeFile.txt [/A]
   echo/
   echo If /A switch is given, anyCommand output is *appended* to teeFile.txt
   goto :EOF
)

if "%2" equ ":TeeProcess" goto TeeProcess

rem Get the output of CLS command
for /F %%a in ('cls') do set "cls=%%a"

rem If /A switch is not provided, delete the file that receives Tee output
if /I "%~2" neq "/A" if exist %1 del %1

rem Create the semaphore-signal file and start the asynchronous Tee process
echo X > Flag.out
if exist Flag.in del Flag.in
Cscript //nologo //E:JScript "%~F0" | "%~F0" %1 :TeeProcess
del Flag.out
goto :EOF

:TeeProcess
   rem Wait for "Data Available" signal
   if not exist Flag.in goto TeeProcess
   rem Read the line sent by JScript section
   set line=
   set /P line=
   rem Set "Data Read" acknowledgement
   ren Flag.in Flag.out
   rem Check for the standard "End Of piped File" mark
   if "!line!" equ ":_EOF_:" exit /B
   rem Correctly manage CLS command
   if "!line:~0,1!" equ "!cls!" (
      cls
      set "line=!line:~1!"
   )
   rem Duplicate the line in Stdout and the Tee output file
   echo(!line!
   echo(!line!>> %1
goto TeeProcess


@end


// JScript section

var fso = new ActiveXObject("Scripting.FileSystemObject");
// Process all lines of Stdin
while ( ! WScript.Stdin.AtEndOfStream ) {
   // Read the next line from Stdin
   var line = WScript.Stdin.ReadLine();
   // Wait for "Data Read" acknowledgement
   while ( ! fso.FileExists("Flag.out") ) {
      WScript.Sleep(10);
   }
   // Send the line to Batch section
   WScript.Stdout.WriteLine(line);
   // Set "Data Available" signal
   fso.MoveFile("Flag.out", "Flag.in");
}
// Wait for last "Data Read" acknowledgement
while ( ! fso.FileExists("Flag.out") ) {
      WScript.Sleep(10);
}
// Send the standard "End Of piped File" mark
WScript.Stdout.WriteLine(":_EOF_:");
fso.MoveFile("Flag.out", "Flag.in");
Run Code Online (Sandbox Code Playgroud)


Kod*_*101 5

我也在寻找相同的解决方案,经过一些尝试,我成功地在命令提示符中实现了这一点。这是我的解决方案:

@Echo off
for /f "Delims=" %%a IN (xyz.bat) do (
%%a > _ && type _ && type _ >> log.txt
)
@Echo on
Run Code Online (Sandbox Code Playgroud)

它甚至还可以捕获任何 PAUSE 命令。


小智 5

像这样的东西应该可以满足您的需要?

%DATE%_%TIME% > c:\a.txt & type c:\a.txt
ipconfig >> c:\a.txt & type c:\a.txt
ping localhost >> c:\a.txt & type c:\a.txt
pause
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

434901 次

最近记录:

6 年,3 月 前