windows 将批处理标准错误重定向到文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/918619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:33:44  来源:igfitidea点击:

Redirect batch stderr to file

windowsbatch-filecmdstderr

提问by nivlam

I have a batch file that executes a java application. I'm trying to modify it so that whenever an exception occurs, it'll write the STDERR out to a file.

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

It looks something like this:

它看起来像这样:

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

Is there a way I can write the arguments %1 and %2 to the log.txt file as well? I don't want to write it to the log file everytime this batch file gets called, only when an exception occurs.

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

I tried searching for a way to redirect STDERR into a variable, but I couldn't figure it out. Ideally I'd like the log file to look something like:

我尝试寻找一种将 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...

回答by Jay

Something like this might work:

像这样的事情可能会奏效:

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
)

I am not a java programmer myself, I cannot test this output/situation but:

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

1:%*means every parameters, from 1st to last (even %12 although it's not directly available.. ) whatever the formating. Might be better to use this than delimit those. In the even of bad spacing/quoting, you would have the full parameters too. I added a line in the log, to show the full line then the parameters. You can see where the problem was if it's a matter of bad arguments.

1: %*表示每个参数,从第一个到最后一个(甚至 %12,尽管它不是直接可用的..),无论格式如何。使用它可能比分隔那些更好。即使是错误的间距/引用,您也将拥有完整的参数。我在日志中添加了一行,以显示完整的行然后是参数。如果是错误的论据,您可以看到问题出在哪里。

2:sending the stdout to null (^>nul) will only keep the stderr output, set into %%e

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

3:Whatever is in the dopart will only happen is the fortest statement actually has anything as an output, i.e. if %%eis set.

3:不管是在部分只会发生是测试实际上说法有什么作为输出,也就是说,如果%%Ë设置。

With those being said, you have to test the script and see if the exception is actually sent to stderr or, like some other softwares, to stdout even if an error occured.

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

I hope this helps.

我希望这有帮助。

回答by Joey

The only working solution I see would be to redirect stderr to a temporary file

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

java blah.jar %1 %2 2>stderr

and afterwards looking whether something has been written to the file and writing to the log in that case.

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

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

If the batches aren't run in sequence but rather simultaneously you need to find something to uniquify the temp variable:

如果批次不是按顺序运行而是同时运行,您需要找到一些东西来统一临时变量:

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
)

This will avoid clashes between multiple running batches. However, you are currently not using anything to lock writing to your log file and things may appear out of place when other things get written to it (with other batches you might get interleaving in the echoand typecommands or, when you're redirecting output of java to that file as well, then it may get mixed up with regular output of the java program:

这将避免多个运行批次之间的冲突。但是,您目前没有使用任何东西来锁定对日志文件的写入,并且当其他内容写入它时,事情可能会显得不合适(对于其他批次,您可能会在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

You can use another file as semaphore for writing to the log to avoid the batch outputs getting mixed: create the file [copy nul file] when you want to write to the log, delete it afterwards and before you attempt to create it check whether it is actually there and wait until it disappears. You can't do anything about the stdout log being mixed into the file, though, except you use that temp file approach for stdout as well (and simply typethe stdout log to log.txtwhen the Java program finished, but, again with using the semaphore.

您可以使用另一个文件作为写入日志的信号量,以避免批量输出混合:copy nul file当您想写入日志时创建文件 [ ],之后删除它并在尝试创建它之前检查它是否确实存在并等到它消失。但是,您不能对混合到文件中的 stdout 日志做任何事情,除非您也对 stdout 使用该临时文件方法(并且只是在 Java 程序完成时将typestdout 日志记录到log.txt,但是,再次使用信号量。

回答by Cheeso

I don't get exactly what you are asking, but here's some info that may help...

我不完全明白你在问什么,但这里有一些信息可能会有所帮助......

You can redirect stderr separately from stdout in a .cmd or .bat file. To redirect stderr, use something like this:

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

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

Then, you can check the command.stderr.txt for content, and if any is present, concatenate it to the command.stdout.txt into your log file. Or you could concat it in any case. If you like you could also echo the command that you ran, into the final log file.

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

You can also check for the exit code in a batch file, using the %ERRORLEVEL% env var. Exe files are expected to set ERRORLEVEL in case of an error. I don't know if java.exe does this. It should, if it is a good citizen on Windows. This might be an alternative way of finding out if the Java app exited with an error condition. But this is no guarantee that stderr got nothing. For example, a Java app might print out an exception and stack trace, and then exit with code 0, which indicates success. In which case stderr would have gunk in it, but ERRORLEVEL would be zero.

您还可以使用 %ERRORLEVEL% 环境变量检查批处理文件中的退出代码。如果出现错误,exe 文件应该设置 ERRORLEVEL。我不知道 java.exe 是否这样做。它应该,如果它是 Windows 上的好公民。这可能是确定 Java 应用程序是否以错误条件退出的另一种方法。但这并不能保证 stderr 一无所获。例如,Java 应用程序可能会打印出异常和堆栈跟踪,然后以代码 0 退出,这表示成功。在这种情况下,stderr 中会有垃圾,但 ERRORLEVEL 将为零。

EDIT: s/ERROR_LEVEL/ERRORLEVEL

编辑:s/ERROR_LEVEL/ERRORLEVEL

回答by SpliFF

Try using ERRORLEVEL

尝试使用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

回答by cdonner

How about something like this (untested):

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

@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

回答by William B-R

A batch file like this should do the trick.

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

start_prog.cmd

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

Here I'm passing stderr via a pipe and passing arguments as arguments. The output is then appended to a log.txt file.

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

Throw away stdout

扔掉标准输出

1>nul

Redirect stderr to stdout

将标准错误重定向到标准输出

2>&1

Pipe the stderr into a script to format the output, and pass arguments as arguments.

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

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

Append output to a "log.txt".

将输出附加到"log.txt"

>>log.txt

On my system I need to call python.exe otherwise the pipe doesn't work.

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

Here are the two files I used "something.py"and "format_output.py".

这是我使用的两个文件"something.py""format_output.py"

something.py

东西.py

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

format_output.py

格式输出.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

And finaly here's the output.

最后是输出。

log.txt

日志文件

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

The only thing missing is that something is always written to the "log.txt"file.

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

To tidy this up further I would move writing the log file into "format_output.py".

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

You could then add a check to see if the stderr from your program is blank.

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