将批处理 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...
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.
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.
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:
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我看到的唯一可行的解决方案是将 stderr 重定向到临时文件
,然后查看是否已将某些内容写入该文件并在这种情况下写入日志。
如果批次不是按顺序运行而是同时运行,您需要找到一些东西来唯一化临时变量:
这将避免多个运行批次之间的冲突。 但是,您当前没有使用任何东西来锁定对日志文件的写入,并且当其他内容写入日志文件时,事情可能会显得不合适(对于其他批次,您可能会在
echo
和中交错>type
命令,或者,当您将 java 的输出也重定向到该文件时,它可能会与 java 程序的常规输出混淆:您可以使用另一个文件作为信号量来写入日志避免批处理输出混合:当您想要写入日志时创建文件 [
copy nul file
],然后将其删除,然后在尝试创建它之前检查它是否确实存在并等待但是,您无法对混合到文件中的 stdout 日志执行任何操作,除非您也对 stdout 使用临时文件方法(并且只需将 stdout 日志键入
到log.txt
当 Java 程序完成时,但是再次使用信号量。The only working solution I see would be to redirect stderr to a temporary file
and afterwards looking whether something has been written to the file and writing to the log in that case.
If the batches aren't run in sequence but rather simultaneously you need to find something to uniquify the temp variable:
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
andtype
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: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 simplytype
the stdout log tolog.txt
when the Java program finished, but, again with using the semaphore.我不明白你在问什么,但这里有一些信息可能会有所帮助...
你可以在 .cmd 或 .bat 文件中将 stderr 与 stdout 分开重定向。 要重定向 stderr,请使用如下内容:
然后,您可以检查 command.stderr.txt 中的内容,如果存在,请将其与 command.stdout.txt 连接到日志文件中。 或者你可以在任何情况下连接它。 如果您愿意,还可以将您运行的命令回显到最终日志文件中。
您还可以使用 %ERRORLEVEL% 环境变量检查批处理文件中的退出代码。 Exe 文件预计会在出现错误时设置 ERRORLEVEL。 我不知道java.exe是否执行此操作。 如果它是 Windows 上的好公民,那么应该如此。 这可能是查明 Java 应用程序是否因错误情况退出的另一种方法。 但这并不能保证 stderr 一无所获。 例如,Java 应用程序可能会打印出异常和堆栈跟踪,然后以代码 0 退出,这表示成功。 在这种情况下,stderr 中会有垃圾,但 ERRORLEVEL 将为零。
编辑:s/ERROR_LEVEL/ERRORLEVEL
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:
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.
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.
EDIT: s/ERROR_LEVEL/ERRORLEVEL
像这样的东西可能会起作用:
javastart.cmd
我自己不是 java 程序员,我无法测试此输出/情况,但是:
1: %* > 表示每个参数,从第一个到最后一个(甚至 %12,尽管它不能直接可用..),无论格式如何。 使用它可能比划定它们更好。 即使间距/引用不好,您也将拥有完整的参数。 我在日志中添加了一行,以显示完整的行,然后显示参数。 如果争论不顺利,你就能看出问题出在哪里。
2: 将 stdout 发送到 null (^>nul) 将仅保留 stderr 输出,设置为 %%e
3: 无论是什么仅当 for 测试语句实际上有任何内容作为输出时,即 %%e 设置时,才会发生 do 部分中的情况。
话虽如此,您必须测试脚本并查看异常是否确实发送到 stderr,或者像其他一些软件一样发送到 stdout,即使发生错误也是如此。
我希望这有帮助。
Something like this might work:
javastart.cmd
I am not a java programmer myself, I cannot test this output/situation but:
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.
2: sending the stdout to null (^>nul) will only keep the stderr output, set into %%e
3: Whatever is in the do part will only happen is the for test statement actually has anything as an output, i.e. if %%e is set.
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.
I hope this helps.
像这样的事情怎么样(未经测试):
How about something like this (untested):
尝试使用 ERRORLEVEL
Try using ERRORLEVEL
像这样的批处理文件应该可以解决问题。
start_prog.cmd
在这里,我通过管道传递 stderr 并将参数作为参数传递。 然后输出将附加到 log.txt 文件中。
丢弃 stdout
将 stderr 重定向到 stdout 将
stderr 通过管道传输到脚本中以格式化输出,并将参数作为参数传递。
将输出附加到“log.txt”。
在我的系统上,我需要调用 python.exe,否则管道将无法工作。
这是我使用的两个文件“something.py”和“format_output.py”。
something.py
format_output.py
最后这是输出。
log.txt
唯一缺少的是总是将某些内容写入“log.txt” 文件中。
为了进一步整理这个问题,我将把日志文件写入“format_output.py”。
然后,您可以添加一个检查来查看程序中的 stderr 是否为空。
A batch file like this should do the trick.
start_prog.cmd
Here I'm passing stderr via a pipe and passing arguments as arguments. The output is then appended to a log.txt file.
Throw away stdout
Redirect stderr to stdout
Pipe the stderr into a script to format the output, and pass arguments as arguments.
Append output to a "log.txt".
On my system I need to call python.exe otherwise the pipe doesn't work.
Here are the two files I used "something.py" and "format_output.py".
something.py
format_output.py
And finaly here's the output.
log.txt
The only thing missing is that something is always written to the "log.txt" file.
To tidy this up further I would move writing the log file into "format_output.py".
You could then add a check to see if the stderr from your program is blank.