如何回显并将控制台输出发送到bat脚本中的文件?

时间:2009-02-02 16:38:02

标签: windows batch-file cmd

我有一个执行任务的批处理脚本并将输出发送到文本文件。有没有办法在控制台窗口上显示输出?

例如:

c:\Windows>dir > windows-dir.txt

有没有办法让dir的输出显示在控制台窗口中,并将其放入文本文件中?

11 个答案:

答案 0 :(得分:209)

不,你不能用纯粹的重定向 但是你可以使用一些技巧(比如tee.bat)。

我尝试稍微解释重定向。

您使用>重定向十个流中的一个档案<文件
如果重定向在命令之前或之后,它是不重要的, 所以这两行几乎相同。

dir > file.txt
> file.txt dir

此示例中的重定向只是 1> 的快捷方式,这意味着将重定向流1(STDOUT)。 因此,您可以使用前面的数字重定向任何流,例如 2> err.txt ,也允许在一行中重定向多个流。

dir 1> files.txt 2> err.txt 3> nothing.txt

在此示例中,“standard output”将进入files.txt,所有错误都将出现在err.txt中,stream3将进入nothing.txt(DIR不使用流3)。
Stream0是STDIN
Stream1是STDOUT
Stream2是STDERR
未使用Stream3-9

但是如果您尝试多次重定向同一个流会发生什么?

dir > files.txt > two.txt

“只能有一个”,它始终是最后一个! 所以它等于 dir> two.txt

好的,还有一种可能性,即将流重定向到另一个流。

dir 1>files.txt 2>&1 

2>& 1 将stream2重定向到stream1, 1> files.txt 将所有内容重定向到 files.txt
订单在这里很重要!

dir ... 1>nul 2>&1
dir ... 2>&1 1>nul

是不同的。第一个将所有(STDOUT和STDERR)重定向到NUL,
但第二行将STDOUT重定向到NUL和STDERR为“空”STDOUT。

作为一个结论,很显然为什么OtávioDécio和andynormancx的例子无效。

command > file >&1
dir > file.txt >&2

两者都尝试重定向stream1两次,但“只能有一个”,并且它始终是最后一个。
所以你得到了

command 1>&1
dir 1>&2

在第一个示例中,不允许将stream1重定向到stream1(并且不是很有用)。

希望它有所帮助。

答案 1 :(得分:32)

以这种方式使用Windows版本的UNIX tee命令(从http://unxutils.sourceforge.net找到):

mycommand > tee outpu_file.txt

如果您还需要STDERR输出,请使用以下内容 2>&1将STDERR输出组合成STDOUT(主流)。

mycommand 2>&1 | tee output_file.txt

答案 2 :(得分:9)

如果您不需要实时输出(即程序正在编写),您可以添加

type windows-dir.txt

之后。

答案 3 :(得分:7)

对我有用的解决方案是:dir > a.txt | type a.txt

答案 4 :(得分:6)

是的,有一种方法可以在控制台(屏幕)和文件中显示单个命令输出。使用您的示例,使用...

@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt

详细说明:

FOR命令将命令或文本的输出解析为变量,可以多次引用该变量。

对于命令,例如DIR /B,请用单引号括起来,如下例所示。用您想要的命令替换DIR /B文本。

FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT

要显示文本,请将文本用双引号括起来,如下例所示。

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT

......还有换行......

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
  ECHO %%I & ECHO %%I>>FILE.TXT
)

如果您有时希望仅在控制台(屏幕)上输出,而其他时间只发送到文件,并且其他时间发送到两者,请使用变量指定FOR循环的“DO”子句,如图所示以下%TOECHOWHERE%

@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
  FOR %%J IN (TRUE FALSE) DO (
    SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish

:Runit
  REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
  REM above when the FOR loops are evaluating the first item in the list,
  REM "TRUE".  So, the first value of TOSCREEN is "TRUE " (with a trailing
  REM space), the second value is "FALSE" (no trailing or leading space).
  REM Adding the ": =" text after "TOSCREEN" tells the command processor to
  REM remove all spaces from the value in the "TOSCREEN" variable.
  IF "%TOSCREEN: =%"=="TRUE" (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=On screen, and in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
        ) ELSE (
          SET TEXT=On screen, not in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I"
      )
    ) ELSE (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=Not on screen, but in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>>FILE.txt"
        ) ELSE (
          SET TEXT=Not on screen, nor in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>NUL"
      )
  )
  FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof

:Finish
  ECHO Finished [this text to console (screen) only].
  PAUSE

答案 5 :(得分:3)

command > file >&1

答案 6 :(得分:2)

如果要追加而不是替换输出文件,可能需要使用

     if ($this->request->is('post')) {


         $filter_url['controller'] = $this->request->params['controller'];
           $filter_url['action'] = $this->request->params['action'];
           $filter_url['page'] = 1;

    // for each filter we will add a GET parameter for the generated url
    foreach($this->request->data as $name => $value){
       if($value){
           $filter_url[$name] = urlencode($value);
       }
    }   
    //Post params are now GET paramaters
    return $this->redirect($filter_url);


    } 




 debug($this->request->params['pass'] ); //outputs nothing


       foreach($this->request->params['pass'] as $param_name => $value):
        // debug($param_name);
           //    debug($value);
            if ($param_name=='lastname')  $searchLastName =$value;
            if ($param_name=='firstname')  $searchFirstName =$value;


        endforeach;

//view
 <?php echo $this->Form->create(); ?>
     <table cellpadding="0" cellspacing="0">
        <thead>
            <tr>


                <td><?php   echo $this->Form->input('firstname',['label' => 'FirstName']); ?></td>
                 <td><?php   echo $this->Form->input('lastname',['label' => ' LastName']); ?></td>
                <td> <?php //echo $this->Form->button('Submit Form', ['name'=>'search','type' => 'submit']); ?></td>
            </tr>
        </thead>

    <?= $this->Form->button('Submit Form', ['name'=>'search','type' => 'submit']); ?>
    <?= $this->Form->end() ?>

http://book.cakephp.org/3.0/en/controllers/request-response.html

var you = items.Where(x=>x.Id == myId).FirstOrDefault();
var allAbove = items.Where(x=>x.Id!=you.Id)
.Where(x=>x.TotalPoint>you.TotalPoints || x.CorrectTrends>you.CorrectTrends);

答案 7 :(得分:1)

我喜欢atn的回答,但对我来说下载wintee并不是一件轻而易举的事,Displaying Windows command prompt output and redirecting it to a file也是开源的,只提供了tee功能(如果你只想要tee而不是整套unix,那就很有用公用事业)。我从davor对{{3}}的回答中了解到了这一点,在那里你也可以找到对unix实用程序的引用。

答案 8 :(得分:1)

我的选择是:

创建一个接收消息的子例程,并自动将其发送到控制台和日志文件。

setlocal
set logfile=logfile.log

call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"    

goto :eof

:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b

如果在邮件中添加变量,请务必在将其发送到子例程之前删除其中的引号,否则可能会导致批处理。 当然这只适用于回声。

答案 9 :(得分:1)

我制作了一个简单的C#控制台,它可以处理cmd屏幕和日志的实时输出

class Tee
{
    static int Main(string[] args)
    {
        try
        {
            string logFilePath = Path.GetFullPath(args[0]);

            using (StreamWriter writer = new StreamWriter(logFilePath, true))
            {
                for (int value; (value = Console.In.Read()) != -1;)
                {
                    var word = Char.ConvertFromUtf32(value);
                    Console.Write(word);
                    writer.Write(word);
                }
            }
        }
        catch (Exception)
        {
            return 1;
        }
        return 0;
    }
}

批处理文件的使用方法与使用Unix tee

的方式相同
foo | tee xxx.log

这是包含Tee.exe的存储库,以防您无法编译工具 https://github.com/iamshiao/Tee

答案 10 :(得分:0)

“Tomas R”提供的解决方案非常适合OP的问题,并且本机可用。

尝试: chkdsk c:&gt; output.txt |输入output.txt

该命令的输出涉及一个完整的百分比,它被串行输出到文件,因此它看起来有点乱(即文本将随着它的进展而附加)。输出到STDOUT(屏幕)的位不会发生这种情况。如果你只是在没有重定向的情况下执行相同的命令,那就是这样。