Перенаправить пакетный 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...
Ответы
Ответ 1
Что-то вроде этого может работать:
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 (^ > nul) приведет к сохранению вывода stderr, установленному в %% e
3: Все, что находится в do, произойдет только в том, что тестовый оператор для фактически имеет что-то в качестве вывода, т.е. если %% e.
С учетом сказанного вам нужно протестировать script и посмотреть, действительно ли исключение отправлено в stderr или, как и другие программные средства, в stdout, даже если произошла ошибка.
Надеюсь, это поможет.
Ответ 2
Я не понимаю, что вы просите, но вот информация, которая может помочь...
Вы можете перенаправить stderr отдельно от stdout в файле .cmd или .bat. Чтобы перенаправить 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 будет иметь гнал в нем, но ERRORLEVEL будет равен нулю.
EDIT: s/ERROR_LEVEL/ERRORLEVEL
Ответ 3
Единственным рабочим решением, которое я вижу, было бы перенаправление 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
)
Если партии не запускаются последовательно, но, скорее, вам нужно найти что-то, чтобы идентифицировать временную переменную:
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
)
Это позволит избежать столкновений между несколькими запущенными партиями. Тем не менее, вы в настоящее время не используете что-либо, чтобы заблокировать запись в файл журнала, и все может показаться неуместным, когда к нему записываются другие вещи (с другими партиями вы можете чередовать в командах 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
Вы можете использовать другой файл в качестве семафора для записи в журнал, чтобы избежать смешанных выходов: создать файл [ copy nul file
], когда вы хотите записать в журнал, удалить его потом и прежде, чем попытаться создать его проверьте, действительно ли он там, и подождите, пока он не исчезнет. Однако вы не можете ничего сделать из-за того, что журнал stdout смешался с файлом, за исключением того, что вы используете этот временный файл для stdout (и просто type
журнал stdout до log.txt
, когда программа Java закончила, но, снова с использованием семафора.
Ответ 4
Как насчет чего-то вроде этого (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
Ответ 5
Попробуйте использовать 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
Ответ 6
Такой командный файл должен делать трюк.
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 с script для форматирования вывода и передайте аргументы в качестве аргументов.
| "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 из вашей программы.