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
Redirect batch stderr to file
提问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 echo
and type
commands 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:
这将避免多个运行批次之间的冲突。但是,您目前没有使用任何东西来锁定对日志文件的写入,并且当其他内容写入它时,事情可能会显得不合适(对于其他批次,您可能会在echo
和type
命令中交错,或者当您重定向输出时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 type
the stdout log to log.txt
when the Java program finished, but, again with using the semaphore.
您可以使用另一个文件作为写入日志的信号量,以避免批量输出混合:copy nul file
当您想写入日志时创建文件 [ ],之后删除它并在尝试创建它之前检查它是否确实存在并等到它消失。但是,您不能对混合到文件中的 stdout 日志做任何事情,除非您也对 stdout 使用该临时文件方法(并且只是在 Java 程序完成时将type
stdout 日志记录到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 是否为空白。