将批处理stderr重定向到文件

时间:2009-05-28 00:24:05

标签: windows batch-file cmd stderr

我有一个执行java应用程序的批处理文件。我正在尝试修改它,以便每当发生异常时,它都会将STDERR写入文件。

它看起来像这样:

start java something.jar method %1 %2 2>> log.txt

有没有办法可以将参数%1和%2写入log.txt文件?每次调用此批处理文件时,我都不想将其写入日志文件,只有在发生异常时才会将其写入日志文件。

我试图找到一种将STDERR重定向到变量的方法,但我无法理解。理想情况下,我希望日志文件看起来像:

Batch file called with parameters:
- "first arg"
- "second arg"
Exception: 
java.io.exception etc...

------------------------------------

Batch file called with parameters:
- "first arg"
- "second arg"
Exception: 
java.io.exception etc...

6 个答案:

答案 0 :(得分:3)

这样的事可能有用:

<强> javastart.cmd

@echo off
set params=%*
for /f "delims=" %%e in ('java something.jar method %1 %2 ^>nul') do (
    echo Batch file called with parameters:>>log.txt
    echo - Args[]: %*>>log.txt
    echo - Arg[1]: %1>>log.txt
    echo - Arg[2]: %2>>log.txt
    echo Exception: %%e
)

我自己不是java程序员,我无法测试此输出/情况但是:

1: %* 表示每个参数,从第1个到最后一个(即使%12,但它不能直接使用..)无论格式化。可能更好地使用它而不是划定它们。即使间距/引用不好,您也可以获得完整的参数。我在日志中添加了一行,以显示完整的行然后参数。如果这是一个不好的论点,你可以看到问题出在哪里。

2:将stdout发送到null(^&gt; nul)只会保留stderr输出,设置为 %% e

3: 执行部分只会发生 for 测试语句实际上有任何输出,即<设置了strong> %% e 。

说到这些,你必须测试脚本并查看异常是否实际发送到stderr,或者像其他软件一样,即使发生错误也要发送到stdout。

我希望这会有所帮助。

答案 1 :(得分:2)

我没有得到你所要求的,但这里有一些可能有帮助的信息......

您可以在.cmd或.bat文件中将stderr与stdout分开重定向。要重定向stderr,请使用以下内容:

MyCommand.exe > command.stdout.txt  2> command.stderr.txt

然后,您可以检查command.stderr.txt中的内容,如果存在,则将其与command.stdout.txt连接到您的日志文件中。或者你可以在任何情况下结束它。如果您愿意,也可以将您运行的命令回显到最终的日志文件中。

您还可以使用%ERRORLEVEL%env var检查批处理文件中的退出代码。如果出现错误,Exe文件应设置ERRORLEVEL。我不知道java.exe是否这样做。它应该,如果它是Windows上的好公民。这可能是一种查找Java应用程序是否以错误条件退出的替代方法。但这并不能保证stderr什么都没得到。例如,Java应用程序可能会打印出异常和堆栈跟踪,然后使用代码0退出,这表示成功。在这种情况下,stderr会有gunk,但ERRORLEVEL将为零。

编辑:s / ERROR_LEVEL / ERRORLEVEL

答案 2 :(得分:2)

我看到的唯一可行解决方案是将stderr重定向到临时文件

java blah.jar %1 %2 2>stderr

然后查看是否已将某些内容写入该文件并在该情况下写入日志。

for %%i in (stderr) do if %%~zi GTR 0 (
    echo Parameters: %1 %2 >>log.txt
    type stderr >> log.txt
)

如果批次没有按顺序运行,而是同时你需要找到一些东西来统一temp变量:

set file=%time::=%
set /a file=file
set file=%file%%random%
java blah.jar %1 %2 2>stderr_%file%
for %%i in (stderr) do if %%~zi GTR 0 (
    echo Parameters: %1 %2 >>log.txt
    type stderr >> log.txt
)

这将避免多个运行批次之间的冲突。但是,您当前没有使用任何东西来锁定对日志文件的写入,并且当其他内容写入其中时,事情可能显得不合适(其他批次可能会在echotype中交错命令,或者,当您将java的输出重定向到该文件时,它可能会与java程序的常规输出混淆:

Parameters: foo bar
Some regular output
Parameters: foo2 bar2
More output
NullPointerException at Blah: What we really wanted to have right after the parameters
IOException at Blah: This exception belongs to the parameters foo2 bar2

您可以使用另一个文件作为信号量来写入日志以避免批处理输出混合:当您想要写入日志时创建文件[copy nul file],之后删除它并在尝试之前创建它检查它是否实际存在并等待它消失。但是,除了对stdout使用该临时文件方法之外,你无法对混合到文件中的stdout日志做任何事情(当Java程序时,只需type stdout登录到log.txt完成了,但是,再次使用信号量。

答案 3 :(得分:0)

这样的事情(未经测试):

@echo off
@echo Batch file called with parameters: >> log.txt
@echo - %1 >> log.txt
@echo - %2 >> log.txt
start java something.jar method %1 %2 2>> log.txt

答案 4 :(得分:0)

尝试使用ERRORLEVEL

java something.jar method %1 %2 2>> log.txt
IF %ERRORLEVEL% NEQ 0 GOTO Error

Error:
@ECHO There was an error
@ECHO Arg 1: %1 >> log.txt
@ECHO Arg 2: %2 >> log.txt

答案 5 :(得分:0)

像这样的批处理文件应该可以解决问题。

<强> start_prog.cmd

CALL :Start_Prog arg1 arg2
GOTO :EOF

:Start_Prog
    something.py %1 %2 2>&1 1>nul | "C:\Python26\python.exe" format_output.py %1 %2 >>log.txt
    GOTO :EOF

这里我通过管道传递stderr并将参数作为参数传递。然后将输出附加到log.txt文件。

扔掉stdout

1>nul

将stderr重定向到stdout

2>&1

将stderr传输到脚本中以格式化输出,并将参数作为参数传递。

| "C:\Python26\python.exe" format_output.py %1 %2

将输出附加到“log.txt”

>>log.txt

在我的系统上,我需要调用python.exe,否则管道不起作用。

以下是我使用的两个文件“something.py”“format_output.py”

<强> something.py

import sys
print >>sys.stdout, " ".join(sys.argv[1:])
print >>sys.stderr, "java.io.exception etc..."

<强> format_output.py

import sys

print "Batch file called with parameters:"
for arg in sys.argv[1:]:
    print '- "{0}"'.format(arg)

print "Exception:"
for line in sys.stdin:
    print line

最后这里是输出。

<强> log.txt的

Batch file called with parameters:
- "arg1"
- "arg2"
Exception:
java.io.exception etc...

唯一缺少的是始终将某些内容写入“log.txt”文件。

为了进一步整理,我会将日志文件写入“format_output.py”

然后,您可以添加一项检查,以查看程序中的stderr是否为空白。